From fe39cd6c6031c1efc1e4da0356fbf5d3f1e701cd Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Mon, 4 May 2026 12:38:52 +0200 Subject: [PATCH] =?UTF-8?q?-=20[NEW]=20Ara=20usa=20Lua=205.5.0=20-=20[NEW]?= =?UTF-8?q?=20Lua=20ara=20es=20una=20llibreria=20est=C3=A0tica,=20pa=20no?= =?UTF-8?q?=20compilarlo=20cada=20vegada=20(Linux,=20falta=20en=20Windows)?= =?UTF-8?q?=20-=20[FIX]=20Arreglats=20mig=20kilo=20de=20warnings=20-=20[FI?= =?UTF-8?q?X]=20include=20=20per=20a=20lua.debug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lagueirtofile | 4 +- source/external/lua/lapi.c | 1455 ---------------------- source/external/lua/lapi.h | 56 +- source/external/lua/lauxlib.c | 1105 ----------------- source/external/lua/lauxlib.h | 52 +- source/external/lua/lbaselib.c | 528 -------- source/external/lua/lcode.c | 1814 --------------------------- source/external/lua/lcode.h | 17 +- source/external/lua/lcorolib.c | 210 ---- source/external/lua/lctype.c | 64 - source/external/lua/ldblib.c | 483 -------- source/external/lua/ldebug.c | 877 -------------- source/external/lua/ldebug.h | 4 +- source/external/lua/ldo.c | 963 --------------- source/external/lua/ldo.h | 56 +- source/external/lua/ldump.c | 226 ---- source/external/lua/lfunc.c | 294 ----- source/external/lua/lfunc.h | 17 +- source/external/lua/lgc.c | 1728 -------------------------- source/external/lua/lgc.h | 151 ++- source/external/lua/liblua.a | Bin 0 -> 606438 bytes source/external/lua/linit.c | 65 - source/external/lua/liolib.c | 828 ------------- source/external/lua/ljumptab.h | 6 +- source/external/lua/llex.c | 581 --------- source/external/lua/llex.h | 8 +- source/external/lua/llimits.h | 312 ++--- source/external/lua/lmathlib.c | 764 ------------ source/external/lua/lmem.c | 201 --- source/external/lua/lmem.h | 13 +- source/external/lua/loadlib.c | 872 ------------- source/external/lua/lobject.c | 592 --------- source/external/lua/lobject.h | 148 ++- source/external/lua/lopcodes.c | 104 -- source/external/lua/lopcodes.h | 173 ++- source/external/lua/lopnames.h | 4 +- source/external/lua/loslib.c | 430 ------- source/external/lua/lparser.c | 1956 ------------------------------ source/external/lua/lparser.h | 57 +- source/external/lua/lstate.c | 439 ------- source/external/lua/lstate.h | 219 ++-- source/external/lua/lstring.c | 273 ----- source/external/lua/lstring.h | 32 +- source/external/lua/lstrlib.c | 1817 --------------------------- source/external/lua/ltable.c | 971 --------------- source/external/lua/ltable.h | 150 ++- source/external/lua/ltablib.c | 429 ------- source/external/lua/ltm.c | 271 ----- source/external/lua/ltm.h | 26 +- source/external/lua/lua.h | 121 +- source/external/lua/lua.hpp | 7 +- source/external/lua/luaconf.h | 165 +-- source/external/lua/lualib.h | 67 +- source/external/lua/lundump.c | 333 ----- source/external/lua/lundump.h | 14 +- source/external/lua/lutf8lib.c | 289 ----- source/external/lua/lvm.c | 1836 ---------------------------- source/external/lua/lvm.h | 50 +- source/external/lua/lzio.c | 68 -- source/external/lua/lzio.h | 3 +- source/mini/audio/jail_audio.cpp | 86 +- source/mini/lua/lua.debug.cpp | 1 + source/mini/shader/shader.cpp | 10 +- source/mini/version.h | 2 +- 64 files changed, 1232 insertions(+), 23665 deletions(-) delete mode 100644 source/external/lua/lapi.c delete mode 100644 source/external/lua/lauxlib.c delete mode 100644 source/external/lua/lbaselib.c delete mode 100644 source/external/lua/lcode.c delete mode 100644 source/external/lua/lcorolib.c delete mode 100644 source/external/lua/lctype.c delete mode 100644 source/external/lua/ldblib.c delete mode 100644 source/external/lua/ldebug.c delete mode 100644 source/external/lua/ldo.c delete mode 100644 source/external/lua/ldump.c delete mode 100644 source/external/lua/lfunc.c delete mode 100644 source/external/lua/lgc.c create mode 100644 source/external/lua/liblua.a delete mode 100644 source/external/lua/linit.c delete mode 100644 source/external/lua/liolib.c delete mode 100644 source/external/lua/llex.c delete mode 100644 source/external/lua/lmathlib.c delete mode 100644 source/external/lua/lmem.c delete mode 100644 source/external/lua/loadlib.c delete mode 100644 source/external/lua/lobject.c delete mode 100644 source/external/lua/lopcodes.c delete mode 100644 source/external/lua/loslib.c delete mode 100644 source/external/lua/lparser.c delete mode 100644 source/external/lua/lstate.c delete mode 100644 source/external/lua/lstring.c delete mode 100644 source/external/lua/lstrlib.c delete mode 100644 source/external/lua/ltable.c delete mode 100644 source/external/lua/ltablib.c delete mode 100644 source/external/lua/ltm.c delete mode 100644 source/external/lua/lundump.c delete mode 100644 source/external/lua/lutf8lib.c delete mode 100644 source/external/lua/lvm.c delete mode 100644 source/external/lua/lzio.c diff --git a/lagueirtofile b/lagueirtofile index c744835..567e7b6 100644 --- a/lagueirtofile +++ b/lagueirtofile @@ -1,13 +1,13 @@ [linux] cppflags = -D LUA_USE_LINUX -Wall -Os -ffunction-sections -fdata-sections -std=c++20 -Isource -libs = -Wl,--gc-sections -lSDL3 -lGL +libs = -Wl,--gc-sections -lSDL3 -lGL -Lsource/external/lua -llua -ldl -lm executable = mini sourcepath = source+ buildpath = build [linux_debug] default cppflags = -D LUA_USE_LINUX -D DEBUG -g -Wall -std=c++20 -Isource -libs = -lSDL3 -lGL +libs = -lSDL3 -lGL -Lsource/external/lua -llua -ldl -lm executable = mini_debug sourcepath = source+ buildpath = build diff --git a/source/external/lua/lapi.c b/source/external/lua/lapi.c deleted file mode 100644 index f8f70cd..0000000 --- a/source/external/lua/lapi.c +++ /dev/null @@ -1,1455 +0,0 @@ -/* -** $Id: lapi.c $ -** Lua API -** See Copyright Notice in lua.h -*/ - -#define lapi_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include -#include - -#include "lua.h" - -#include "lapi.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lundump.h" -#include "lvm.h" - - - -const char lua_ident[] = - "$LuaVersion: " LUA_COPYRIGHT " $" - "$LuaAuthors: " LUA_AUTHORS " $"; - - - -/* -** Test for a valid index (one that is not the 'nilvalue'). -** '!ttisnil(o)' implies 'o != &G(L)->nilvalue', so it is not needed. -** However, it covers the most common cases in a faster way. -*/ -#define isvalid(L, o) (!ttisnil(o) || o != &G(L)->nilvalue) - - -/* test for pseudo index */ -#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) - -/* test for upvalue */ -#define isupvalue(i) ((i) < LUA_REGISTRYINDEX) - - -static TValue *index2value (lua_State *L, int idx) { - CallInfo *ci = L->ci; - if (idx > 0) { - StkId o = ci->func + idx; - api_check(L, idx <= L->ci->top - (ci->func + 1), "unacceptable index"); - if (o >= L->top) return &G(L)->nilvalue; - else return s2v(o); - } - else if (!ispseudo(idx)) { /* negative index */ - api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); - return s2v(L->top + idx); - } - else if (idx == LUA_REGISTRYINDEX) - return &G(L)->l_registry; - else { /* upvalues */ - idx = LUA_REGISTRYINDEX - idx; - api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); - if (ttislcf(s2v(ci->func))) /* light C function? */ - return &G(L)->nilvalue; /* it has no upvalues */ - else { - CClosure *func = clCvalue(s2v(ci->func)); - return (idx <= func->nupvalues) ? &func->upvalue[idx-1] - : &G(L)->nilvalue; - } - } -} - - -static StkId index2stack (lua_State *L, int idx) { - CallInfo *ci = L->ci; - if (idx > 0) { - StkId o = ci->func + idx; - api_check(L, o < L->top, "unacceptable index"); - return o; - } - else { /* non-positive index */ - api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); - api_check(L, !ispseudo(idx), "invalid index"); - return L->top + idx; - } -} - - -LUA_API int lua_checkstack (lua_State *L, int n) { - int res; - CallInfo *ci; - lua_lock(L); - ci = L->ci; - 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 */ - int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; - if (inuse > LUAI_MAXSTACK - n) /* can grow without overflow? */ - res = 0; /* no */ - else /* try to grow stack */ - res = luaD_growstack(L, n, 0); - } - if (res && ci->top < L->top + n) - ci->top = L->top + n; /* adjust frame top */ - lua_unlock(L); - return res; -} - - -LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { - int i; - if (from == to) return; - lua_lock(to); - api_checknelems(from, n); - api_check(from, G(from) == G(to), "moving among independent states"); - api_check(from, to->ci->top - to->top >= n, "stack overflow"); - from->top -= n; - for (i = 0; i < n; i++) { - setobjs2s(to, to->top, from->top + i); - to->top++; /* stack already checked by previous 'api_check' */ - } - lua_unlock(to); -} - - -LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { - lua_CFunction old; - lua_lock(L); - old = G(L)->panic; - G(L)->panic = panicf; - lua_unlock(L); - return old; -} - - -LUA_API lua_Number lua_version (lua_State *L) { - UNUSED(L); - return LUA_VERSION_NUM; -} - - - -/* -** basic stack manipulation -*/ - - -/* -** convert an acceptable stack index into an absolute index -*/ -LUA_API int lua_absindex (lua_State *L, int idx) { - return (idx > 0 || ispseudo(idx)) - ? idx - : cast_int(L->top - L->ci->func) + idx; -} - - -LUA_API int lua_gettop (lua_State *L) { - return cast_int(L->top - (L->ci->func + 1)); -} - - -LUA_API void lua_settop (lua_State *L, int idx) { - CallInfo *ci; - StkId func, newtop; - ptrdiff_t diff; /* difference for new top */ - lua_lock(L); - ci = L->ci; - func = ci->func; - if (idx >= 0) { - api_check(L, idx <= ci->top - (func + 1), "new top too large"); - diff = ((func + 1) + idx) - L->top; - for (; diff > 0; diff--) - setnilvalue(s2v(L->top++)); /* clear new slots */ - } - else { - api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); - diff = idx + 1; /* will "subtract" index (as it is negative) */ - } - api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot"); - newtop = L->top + diff; - if (diff < 0 && L->tbclist >= newtop) { - lua_assert(hastocloseCfunc(ci->nresults)); - luaF_close(L, newtop, CLOSEKTOP, 0); - } - L->top = newtop; /* correct top only after closing any upvalue */ - lua_unlock(L); -} - - -LUA_API void lua_closeslot (lua_State *L, int idx) { - StkId level; - lua_lock(L); - level = index2stack(L, idx); - api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level, - "no variable to close at given level"); - luaF_close(L, level, CLOSEKTOP, 0); - level = index2stack(L, idx); /* stack may be moved */ - setnilvalue(s2v(level)); - lua_unlock(L); -} - - -/* -** Reverse the stack segment from 'from' to 'to' -** (auxiliary to 'lua_rotate') -** Note that we move(copy) only the value inside the stack. -** (We do not move additional fields that may exist.) -*/ -static void reverse (lua_State *L, StkId from, StkId to) { - for (; from < to; from++, to--) { - TValue temp; - setobj(L, &temp, s2v(from)); - setobjs2s(L, from, to); - setobj2s(L, to, &temp); - } -} - - -/* -** Let x = AB, where A is a prefix of length 'n'. Then, -** rotate x n == BA. But BA == (A^r . B^r)^r. -*/ -LUA_API void lua_rotate (lua_State *L, int idx, int n) { - StkId p, t, m; - lua_lock(L); - t = L->top - 1; /* end of stack segment being rotated */ - p = index2stack(L, idx); /* start of segment */ - 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 */ - reverse(L, p, t); /* reverse the entire segment */ - lua_unlock(L); -} - - -LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { - TValue *fr, *to; - lua_lock(L); - fr = index2value(L, fromidx); - to = index2value(L, toidx); - api_check(L, isvalid(L, to), "invalid index"); - setobj(L, to, fr); - if (isupvalue(toidx)) /* function upvalue? */ - luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr); - /* LUA_REGISTRYINDEX does not need gc barrier - (collector revisits it before finishing collection) */ - lua_unlock(L); -} - - -LUA_API void lua_pushvalue (lua_State *L, int idx) { - lua_lock(L); - setobj2s(L, L->top, index2value(L, idx)); - api_incr_top(L); - lua_unlock(L); -} - - - -/* -** access functions (stack -> C) -*/ - - -LUA_API int lua_type (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return (isvalid(L, o) ? ttype(o) : LUA_TNONE); -} - - -LUA_API const char *lua_typename (lua_State *L, int t) { - UNUSED(L); - api_check(L, LUA_TNONE <= t && t < LUA_NUMTYPES, "invalid type"); - return ttypename(t); -} - - -LUA_API int lua_iscfunction (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return (ttislcf(o) || (ttisCclosure(o))); -} - - -LUA_API int lua_isinteger (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return ttisinteger(o); -} - - -LUA_API int lua_isnumber (lua_State *L, int idx) { - lua_Number n; - const TValue *o = index2value(L, idx); - return tonumber(o, &n); -} - - -LUA_API int lua_isstring (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return (ttisstring(o) || cvt2str(o)); -} - - -LUA_API int lua_isuserdata (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return (ttisfulluserdata(o) || ttislightuserdata(o)); -} - - -LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { - const TValue *o1 = index2value(L, index1); - const TValue *o2 = index2value(L, index2); - return (isvalid(L, o1) && isvalid(L, o2)) ? luaV_rawequalobj(o1, o2) : 0; -} - - -LUA_API void lua_arith (lua_State *L, int op) { - lua_lock(L); - if (op != LUA_OPUNM && op != LUA_OPBNOT) - api_checknelems(L, 2); /* all other operations expect two operands */ - else { /* for unary operations, add fake 2nd operand */ - api_checknelems(L, 1); - setobjs2s(L, L->top, L->top - 1); - api_incr_top(L); - } - /* first operand at top - 2, second at top - 1; result go to top - 2 */ - luaO_arith(L, op, s2v(L->top - 2), s2v(L->top - 1), L->top - 2); - L->top--; /* remove second operand */ - lua_unlock(L); -} - - -LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { - const TValue *o1; - const TValue *o2; - int i = 0; - lua_lock(L); /* may call tag method */ - o1 = index2value(L, index1); - o2 = index2value(L, index2); - if (isvalid(L, o1) && isvalid(L, o2)) { - switch (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(L, 0, "invalid option"); - } - } - lua_unlock(L); - return i; -} - - -LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { - size_t sz = luaO_str2num(s, s2v(L->top)); - if (sz != 0) - api_incr_top(L); - return sz; -} - - -LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) { - lua_Number n = 0; - const TValue *o = index2value(L, idx); - int isnum = tonumber(o, &n); - if (pisnum) - *pisnum = isnum; - return n; -} - - -LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) { - lua_Integer res = 0; - const TValue *o = index2value(L, idx); - int isnum = tointeger(o, &res); - if (pisnum) - *pisnum = isnum; - return res; -} - - -LUA_API int lua_toboolean (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return !l_isfalse(o); -} - - -LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { - TValue *o; - lua_lock(L); - o = index2value(L, idx); - if (!ttisstring(o)) { - if (!cvt2str(o)) { /* not convertible? */ - if (len != NULL) *len = 0; - lua_unlock(L); - return NULL; - } - luaO_tostring(L, o); - luaC_checkGC(L); - o = index2value(L, idx); /* previous call may reallocate the stack */ - } - if (len != NULL) - *len = vslen(o); - lua_unlock(L); - return svalue(o); -} - - -LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - switch (ttypetag(o)) { - case LUA_VSHRSTR: return tsvalue(o)->shrlen; - case LUA_VLNGSTR: return tsvalue(o)->u.lnglen; - case LUA_VUSERDATA: return uvalue(o)->len; - case LUA_VTABLE: return luaH_getn(hvalue(o)); - default: return 0; - } -} - - -LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - if (ttislcf(o)) return fvalue(o); - else if (ttisCclosure(o)) - return clCvalue(o)->f; - else return NULL; /* not a C function */ -} - - -static void *touserdata (const TValue *o) { - switch (ttype(o)) { - case LUA_TUSERDATA: return getudatamem(uvalue(o)); - case LUA_TLIGHTUSERDATA: return pvalue(o); - default: return NULL; - } -} - - -LUA_API void *lua_touserdata (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return touserdata(o); -} - - -LUA_API lua_State *lua_tothread (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - return (!ttisthread(o)) ? NULL : thvalue(o); -} - - -/* -** Returns a pointer to the internal representation of an object. -** Note that ANSI C does not allow the conversion of a pointer to -** function to a 'void*', so the conversion here goes through -** a 'size_t'. (As the returned pointer is only informative, this -** conversion should not be a problem.) -*/ -LUA_API const void *lua_topointer (lua_State *L, int idx) { - const TValue *o = index2value(L, idx); - switch (ttypetag(o)) { - case LUA_VLCF: return cast_voidp(cast_sizet(fvalue(o))); - case LUA_VUSERDATA: case LUA_VLIGHTUSERDATA: - return touserdata(o); - default: { - if (iscollectable(o)) - return gcvalue(o); - else - return NULL; - } - } -} - - - -/* -** push functions (C -> stack) -*/ - - -LUA_API void lua_pushnil (lua_State *L) { - lua_lock(L); - setnilvalue(s2v(L->top)); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { - lua_lock(L); - setfltvalue(s2v(L->top), n); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { - lua_lock(L); - setivalue(s2v(L->top), n); - api_incr_top(L); - lua_unlock(L); -} - - -/* -** Pushes on the stack a string with given length. Avoid using 's' when -** 'len' == 0 (as 's' can be NULL in that case), due to later use of -** 'memcmp' and 'memcpy'. -*/ -LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { - TString *ts; - lua_lock(L); - ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len); - setsvalue2s(L, L->top, ts); - api_incr_top(L); - luaC_checkGC(L); - lua_unlock(L); - return getstr(ts); -} - - -LUA_API const char *lua_pushstring (lua_State *L, const char *s) { - lua_lock(L); - if (s == NULL) - setnilvalue(s2v(L->top)); - else { - TString *ts; - ts = luaS_new(L, s); - setsvalue2s(L, L->top, ts); - s = getstr(ts); /* internal copy's address */ - } - api_incr_top(L); - luaC_checkGC(L); - lua_unlock(L); - return s; -} - - -LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, - va_list argp) { - const char *ret; - lua_lock(L); - ret = luaO_pushvfstring(L, fmt, argp); - luaC_checkGC(L); - lua_unlock(L); - return ret; -} - - -LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { - const char *ret; - va_list argp; - lua_lock(L); - va_start(argp, fmt); - ret = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - luaC_checkGC(L); - lua_unlock(L); - return ret; -} - - -LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { - lua_lock(L); - if (n == 0) { - setfvalue(s2v(L->top), fn); - api_incr_top(L); - } - else { - CClosure *cl; - api_checknelems(L, n); - api_check(L, n <= MAXUPVAL, "upvalue index too large"); - cl = luaF_newCclosure(L, n); - cl->f = fn; - L->top -= n; - while (n--) { - setobj2n(L, &cl->upvalue[n], s2v(L->top + n)); - /* does not need barrier because closure is white */ - lua_assert(iswhite(cl)); - } - setclCvalue(L, s2v(L->top), cl); - api_incr_top(L); - luaC_checkGC(L); - } - lua_unlock(L); -} - - -LUA_API void lua_pushboolean (lua_State *L, int b) { - lua_lock(L); - if (b) - setbtvalue(s2v(L->top)); - else - setbfvalue(s2v(L->top)); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { - lua_lock(L); - setpvalue(s2v(L->top), p); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API int lua_pushthread (lua_State *L) { - lua_lock(L); - setthvalue(L, s2v(L->top), L); - api_incr_top(L); - lua_unlock(L); - return (G(L)->mainthread == L); -} - - - -/* -** get functions (Lua -> stack) -*/ - - -static int auxgetstr (lua_State *L, const TValue *t, const char *k) { - const TValue *slot; - TString *str = luaS_new(L, k); - if (luaV_fastget(L, t, str, slot, luaH_getstr)) { - setobj2s(L, L->top, slot); - api_incr_top(L); - } - else { - setsvalue2s(L, L->top, str); - api_incr_top(L); - luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot); - } - lua_unlock(L); - return ttype(s2v(L->top - 1)); -} - - -/* -** Get the global table in the registry. Since all predefined -** indices in the registry were inserted right when the registry -** was created and never removed, they must always be in the array -** part of the registry. -*/ -#define getGtable(L) \ - (&hvalue(&G(L)->l_registry)->array[LUA_RIDX_GLOBALS - 1]) - - -LUA_API int lua_getglobal (lua_State *L, const char *name) { - const TValue *G; - lua_lock(L); - G = getGtable(L); - return auxgetstr(L, G, name); -} - - -LUA_API int lua_gettable (lua_State *L, int idx) { - const TValue *slot; - TValue *t; - lua_lock(L); - t = index2value(L, idx); - if (luaV_fastget(L, t, s2v(L->top - 1), slot, luaH_get)) { - setobj2s(L, L->top - 1, slot); - } - else - luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot); - lua_unlock(L); - return ttype(s2v(L->top - 1)); -} - - -LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { - lua_lock(L); - return auxgetstr(L, index2value(L, idx), k); -} - - -LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { - TValue *t; - const TValue *slot; - lua_lock(L); - t = index2value(L, idx); - if (luaV_fastgeti(L, t, n, slot)) { - setobj2s(L, L->top, slot); - } - else { - TValue aux; - setivalue(&aux, n); - luaV_finishget(L, t, &aux, L->top, slot); - } - api_incr_top(L); - lua_unlock(L); - return ttype(s2v(L->top - 1)); -} - - -static int finishrawget (lua_State *L, const TValue *val) { - if (isempty(val)) /* avoid copying empty items to the stack */ - setnilvalue(s2v(L->top)); - else - setobj2s(L, L->top, val); - api_incr_top(L); - lua_unlock(L); - return ttype(s2v(L->top - 1)); -} - - -static Table *gettable (lua_State *L, int idx) { - TValue *t = index2value(L, idx); - api_check(L, ttistable(t), "table expected"); - return hvalue(t); -} - - -LUA_API int lua_rawget (lua_State *L, int idx) { - Table *t; - const TValue *val; - lua_lock(L); - api_checknelems(L, 1); - t = gettable(L, idx); - val = luaH_get(t, s2v(L->top - 1)); - L->top--; /* remove key */ - return finishrawget(L, val); -} - - -LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { - Table *t; - lua_lock(L); - t = gettable(L, idx); - return finishrawget(L, luaH_getint(t, n)); -} - - -LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { - Table *t; - TValue k; - lua_lock(L); - t = gettable(L, idx); - setpvalue(&k, cast_voidp(p)); - return finishrawget(L, luaH_get(t, &k)); -} - - -LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { - Table *t; - lua_lock(L); - t = luaH_new(L); - sethvalue2s(L, L->top, t); - api_incr_top(L); - if (narray > 0 || nrec > 0) - luaH_resize(L, t, narray, nrec); - luaC_checkGC(L); - lua_unlock(L); -} - - -LUA_API int lua_getmetatable (lua_State *L, int objindex) { - const TValue *obj; - Table *mt; - int res = 0; - lua_lock(L); - obj = index2value(L, objindex); - switch (ttype(obj)) { - case LUA_TTABLE: - mt = hvalue(obj)->metatable; - break; - case LUA_TUSERDATA: - mt = uvalue(obj)->metatable; - break; - default: - mt = G(L)->mt[ttype(obj)]; - break; - } - if (mt != NULL) { - sethvalue2s(L, L->top, mt); - api_incr_top(L); - res = 1; - } - lua_unlock(L); - return res; -} - - -LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) { - TValue *o; - int t; - lua_lock(L); - o = index2value(L, idx); - api_check(L, ttisfulluserdata(o), "full userdata expected"); - if (n <= 0 || n > uvalue(o)->nuvalue) { - setnilvalue(s2v(L->top)); - t = LUA_TNONE; - } - else { - setobj2s(L, L->top, &uvalue(o)->uv[n - 1].uv); - t = ttype(s2v(L->top)); - } - api_incr_top(L); - lua_unlock(L); - return t; -} - - -/* -** set functions (stack -> Lua) -*/ - -/* -** t[k] = value at the top of the stack (where 'k' is a string) -*/ -static void auxsetstr (lua_State *L, const TValue *t, const char *k) { - const TValue *slot; - TString *str = luaS_new(L, k); - api_checknelems(L, 1); - if (luaV_fastget(L, t, str, slot, luaH_getstr)) { - luaV_finishfastset(L, t, slot, s2v(L->top - 1)); - L->top--; /* pop value */ - } - else { - setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */ - api_incr_top(L); - luaV_finishset(L, t, s2v(L->top - 1), s2v(L->top - 2), slot); - L->top -= 2; /* pop value and key */ - } - lua_unlock(L); /* lock done by caller */ -} - - -LUA_API void lua_setglobal (lua_State *L, const char *name) { - const TValue *G; - lua_lock(L); /* unlock done in 'auxsetstr' */ - G = getGtable(L); - auxsetstr(L, G, name); -} - - -LUA_API void lua_settable (lua_State *L, int idx) { - TValue *t; - const TValue *slot; - lua_lock(L); - api_checknelems(L, 2); - t = index2value(L, idx); - if (luaV_fastget(L, t, s2v(L->top - 2), slot, luaH_get)) { - luaV_finishfastset(L, t, slot, s2v(L->top - 1)); - } - else - luaV_finishset(L, t, s2v(L->top - 2), s2v(L->top - 1), slot); - L->top -= 2; /* pop index and value */ - lua_unlock(L); -} - - -LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { - lua_lock(L); /* unlock done in 'auxsetstr' */ - auxsetstr(L, index2value(L, idx), k); -} - - -LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { - TValue *t; - const TValue *slot; - lua_lock(L); - api_checknelems(L, 1); - t = index2value(L, idx); - if (luaV_fastgeti(L, t, n, slot)) { - luaV_finishfastset(L, t, slot, s2v(L->top - 1)); - } - else { - TValue aux; - setivalue(&aux, n); - luaV_finishset(L, t, &aux, s2v(L->top - 1), slot); - } - L->top--; /* pop value */ - lua_unlock(L); -} - - -static void aux_rawset (lua_State *L, int idx, TValue *key, int n) { - Table *t; - lua_lock(L); - api_checknelems(L, n); - t = gettable(L, idx); - luaH_set(L, t, key, s2v(L->top - 1)); - invalidateTMcache(t); - luaC_barrierback(L, obj2gco(t), s2v(L->top - 1)); - L->top -= n; - lua_unlock(L); -} - - -LUA_API void lua_rawset (lua_State *L, int idx) { - aux_rawset(L, idx, s2v(L->top - 2), 2); -} - - -LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { - TValue k; - setpvalue(&k, cast_voidp(p)); - aux_rawset(L, idx, &k, 1); -} - - -LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { - Table *t; - lua_lock(L); - api_checknelems(L, 1); - t = gettable(L, idx); - luaH_setint(L, t, n, s2v(L->top - 1)); - luaC_barrierback(L, obj2gco(t), s2v(L->top - 1)); - L->top--; - lua_unlock(L); -} - - -LUA_API int lua_setmetatable (lua_State *L, int objindex) { - TValue *obj; - Table *mt; - lua_lock(L); - api_checknelems(L, 1); - obj = index2value(L, objindex); - if (ttisnil(s2v(L->top - 1))) - mt = NULL; - else { - api_check(L, ttistable(s2v(L->top - 1)), "table expected"); - mt = hvalue(s2v(L->top - 1)); - } - switch (ttype(obj)) { - case LUA_TTABLE: { - hvalue(obj)->metatable = mt; - if (mt) { - luaC_objbarrier(L, gcvalue(obj), mt); - luaC_checkfinalizer(L, gcvalue(obj), mt); - } - break; - } - case LUA_TUSERDATA: { - uvalue(obj)->metatable = mt; - if (mt) { - luaC_objbarrier(L, uvalue(obj), mt); - luaC_checkfinalizer(L, gcvalue(obj), mt); - } - break; - } - default: { - G(L)->mt[ttype(obj)] = mt; - break; - } - } - L->top--; - lua_unlock(L); - return 1; -} - - -LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) { - TValue *o; - int res; - lua_lock(L); - api_checknelems(L, 1); - o = index2value(L, idx); - api_check(L, ttisfulluserdata(o), "full userdata expected"); - if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue))) - res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */ - else { - setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1)); - luaC_barrierback(L, gcvalue(o), s2v(L->top - 1)); - res = 1; - } - L->top--; - lua_unlock(L); - return res; -} - - -/* -** 'load' and 'call' functions (run Lua code) -*/ - - -#define checkresults(L,na,nr) \ - api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ - "results from function overflow current stack size") - - -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(L, k == NULL || !isLua(L->ci), - "cannot use continuations inside hooks"); - api_checknelems(L, nargs+1); - 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 && yieldable(L)) { /* need to prepare continuation? */ - L->ci->u.c.k = k; /* save continuation */ - L->ci->u.c.ctx = ctx; /* save context */ - luaD_call(L, func, nresults); /* do the call */ - } - else /* no continuation or no yieldable */ - luaD_callnoyield(L, func, nresults); /* just do the call */ - adjustresults(L, nresults); - lua_unlock(L); -} - - - -/* -** Execute a protected call. -*/ -struct CallS { /* data to 'f_call' */ - StkId func; - int nresults; -}; - - -static void f_call (lua_State *L, void *ud) { - struct CallS *c = cast(struct CallS *, ud); - luaD_callnoyield(L, c->func, c->nresults); -} - - - -LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, - lua_KContext ctx, lua_KFunction k) { - struct CallS c; - int status; - ptrdiff_t func; - lua_lock(L); - api_check(L, k == NULL || !isLua(L->ci), - "cannot use continuations inside hooks"); - api_checknelems(L, nargs+1); - 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 = index2stack(L, errfunc); - api_check(L, ttisfunction(s2v(o)), "error handler must be a function"); - func = savestack(L, o); - } - c.func = L->top - (nargs+1); /* function to be called */ - if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */ - c.nresults = nresults; /* do a 'conventional' protected call */ - status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); - } - else { /* prepare continuation (call is already protected by 'resume') */ - CallInfo *ci = L->ci; - ci->u.c.k = k; /* save continuation */ - ci->u.c.ctx = ctx; /* save context */ - /* save information for error recovery */ - ci->u2.funcidx = cast_int(savestack(L, c.func)); - ci->u.c.old_errfunc = L->errfunc; - L->errfunc = func; - setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */ - ci->callstatus |= CIST_YPCALL; /* function can do error recovery */ - luaD_call(L, c.func, nresults); /* do the call */ - ci->callstatus &= ~CIST_YPCALL; - L->errfunc = ci->u.c.old_errfunc; - status = LUA_OK; /* if it is here, there were no errors */ - } - adjustresults(L, nresults); - lua_unlock(L); - return status; -} - - -LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, - const char *chunkname, const char *mode) { - ZIO z; - int status; - lua_lock(L); - if (!chunkname) chunkname = "?"; - luaZ_init(L, &z, reader, data); - status = luaD_protectedparser(L, &z, chunkname, mode); - if (status == LUA_OK) { /* no errors? */ - LClosure *f = clLvalue(s2v(L->top - 1)); /* get newly created function */ - if (f->nupvalues >= 1) { /* does it have an upvalue? */ - /* get global table from registry */ - const TValue *gt = getGtable(L); - /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ - setobj(L, f->upvals[0]->v, gt); - luaC_barrier(L, f->upvals[0], gt); - } - } - lua_unlock(L); - return status; -} - - -LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { - int status; - TValue *o; - lua_lock(L); - api_checknelems(L, 1); - o = s2v(L->top - 1); - if (isLfunction(o)) - status = luaU_dump(L, getproto(o), writer, data, strip); - else - status = 1; - lua_unlock(L); - return status; -} - - -LUA_API int lua_status (lua_State *L) { - return L->status; -} - - -/* -** Garbage-collection function -*/ -LUA_API int lua_gc (lua_State *L, int what, ...) { - va_list argp; - int res = 0; - global_State *g; - lua_lock(L); - g = G(L); - va_start(argp, what); - switch (what) { - case LUA_GCSTOP: { - g->gcrunning = 0; - break; - } - case LUA_GCRESTART: { - luaE_setdebt(g, 0); - g->gcrunning = 1; - break; - } - case LUA_GCCOLLECT: { - luaC_fullgc(L, 0); - break; - } - case LUA_GCCOUNT: { - /* GC values are expressed in Kbytes: #bytes/2^10 */ - res = cast_int(gettotalbytes(g) >> 10); - break; - } - case LUA_GCCOUNTB: { - res = cast_int(gettotalbytes(g) & 0x3ff); - break; - } - case LUA_GCSTEP: { - int data = va_arg(argp, int); - l_mem debt = 1; /* =1 to signal that it did an actual step */ - lu_byte oldrunning = g->gcrunning; - g->gcrunning = 1; /* allow GC to run */ - if (data == 0) { - luaE_setdebt(g, 0); /* do a basic step */ - luaC_step(L); - } - else { /* add 'data' to total debt */ - debt = cast(l_mem, data) * 1024 + g->GCdebt; - luaE_setdebt(g, debt); - luaC_checkGC(L); - } - g->gcrunning = oldrunning; /* restore previous state */ - if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ - res = 1; /* signal it */ - break; - } - case LUA_GCSETPAUSE: { - int data = va_arg(argp, int); - res = getgcparam(g->gcpause); - setgcparam(g->gcpause, data); - break; - } - case LUA_GCSETSTEPMUL: { - int data = va_arg(argp, int); - res = getgcparam(g->gcstepmul); - setgcparam(g->gcstepmul, data); - break; - } - case LUA_GCISRUNNING: { - res = g->gcrunning; - break; - } - case LUA_GCGEN: { - int minormul = va_arg(argp, int); - int majormul = va_arg(argp, int); - res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; - if (minormul != 0) - g->genminormul = minormul; - if (majormul != 0) - setgcparam(g->genmajormul, majormul); - luaC_changemode(L, KGC_GEN); - break; - } - case LUA_GCINC: { - int pause = va_arg(argp, int); - int stepmul = va_arg(argp, int); - int stepsize = va_arg(argp, int); - res = isdecGCmodegen(g) ? LUA_GCGEN : LUA_GCINC; - if (pause != 0) - setgcparam(g->gcpause, pause); - if (stepmul != 0) - setgcparam(g->gcstepmul, stepmul); - if (stepsize != 0) - g->gcstepsize = stepsize; - luaC_changemode(L, KGC_INC); - break; - } - default: res = -1; /* invalid option */ - } - va_end(argp); - lua_unlock(L); - return res; -} - - - -/* -** miscellaneous functions -*/ - - -LUA_API int lua_error (lua_State *L) { - TValue *errobj; - lua_lock(L); - errobj = s2v(L->top - 1); - api_checknelems(L, 1); - /* error object is the memory error message? */ - if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg)) - luaM_error(L); /* raise a memory error */ - else - luaG_errormsg(L); /* raise a regular error */ - /* code unreachable; will unlock when control actually leaves the kernel */ - return 0; /* to avoid warnings */ -} - - -LUA_API int lua_next (lua_State *L, int idx) { - Table *t; - int more; - lua_lock(L); - api_checknelems(L, 1); - t = gettable(L, idx); - more = luaH_next(L, t, L->top - 1); - if (more) { - api_incr_top(L); - } - else /* no more elements */ - L->top -= 1; /* remove key */ - lua_unlock(L); - return more; -} - - -LUA_API void lua_toclose (lua_State *L, int idx) { - int nresults; - StkId o; - lua_lock(L); - o = index2stack(L, idx); - nresults = L->ci->nresults; - api_check(L, L->tbclist < o, "given index below or equal a marked one"); - luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */ - if (!hastocloseCfunc(nresults)) /* function not marked yet? */ - L->ci->nresults = codeNresults(nresults); /* mark it */ - lua_assert(hastocloseCfunc(L->ci->nresults)); - lua_unlock(L); -} - - -LUA_API void lua_concat (lua_State *L, int n) { - lua_lock(L); - api_checknelems(L, n); - if (n > 0) - luaV_concat(L, n); - else { /* nothing to concatenate */ - setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); /* push empty string */ - api_incr_top(L); - } - luaC_checkGC(L); - lua_unlock(L); -} - - -LUA_API void lua_len (lua_State *L, int idx) { - TValue *t; - lua_lock(L); - t = index2value(L, idx); - luaV_objlen(L, L->top, t); - api_incr_top(L); - lua_unlock(L); -} - - -LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { - lua_Alloc f; - lua_lock(L); - if (ud) *ud = G(L)->ud; - f = G(L)->frealloc; - lua_unlock(L); - return f; -} - - -LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { - lua_lock(L); - G(L)->ud = ud; - G(L)->frealloc = f; - lua_unlock(L); -} - - -void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) { - lua_lock(L); - G(L)->ud_warn = ud; - G(L)->warnf = f; - lua_unlock(L); -} - - -void lua_warning (lua_State *L, const char *msg, int tocont) { - lua_lock(L); - luaE_warning(L, msg, tocont); - lua_unlock(L); -} - - - -LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) { - Udata *u; - lua_lock(L); - api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value"); - u = luaS_newudata(L, size, nuvalue); - setuvalue(L, s2v(L->top), u); - api_incr_top(L); - luaC_checkGC(L); - lua_unlock(L); - return getudatamem(u); -} - - - -static const char *aux_upvalue (TValue *fi, int n, TValue **val, - GCObject **owner) { - switch (ttypetag(fi)) { - case LUA_VCCL: { /* C closure */ - CClosure *f = clCvalue(fi); - if (!(cast_uint(n) - 1u < cast_uint(f->nupvalues))) - return NULL; /* 'n' not in [1, f->nupvalues] */ - *val = &f->upvalue[n-1]; - if (owner) *owner = obj2gco(f); - return ""; - } - case LUA_VLCL: { /* Lua closure */ - LClosure *f = clLvalue(fi); - TString *name; - Proto *p = f->p; - if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues))) - return NULL; /* 'n' not in [1, p->sizeupvalues] */ - *val = f->upvals[n-1]->v; - if (owner) *owner = obj2gco(f->upvals[n - 1]); - name = p->upvalues[n-1].name; - return (name == NULL) ? "(no name)" : getstr(name); - } - default: return NULL; /* not a closure */ - } -} - - -LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TValue *val = NULL; /* to avoid warnings */ - lua_lock(L); - name = aux_upvalue(index2value(L, funcindex), n, &val, NULL); - if (name) { - setobj2s(L, L->top, val); - api_incr_top(L); - } - lua_unlock(L); - return name; -} - - -LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TValue *val = NULL; /* to avoid warnings */ - GCObject *owner = NULL; /* to avoid warnings */ - TValue *fi; - lua_lock(L); - fi = index2value(L, funcindex); - api_checknelems(L, 1); - name = aux_upvalue(fi, n, &val, &owner); - if (name) { - L->top--; - setobj(L, val, s2v(L->top)); - luaC_barrier(L, owner, val); - } - lua_unlock(L); - return name; -} - - -static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { - static const UpVal *const nullup = NULL; - LClosure *f; - TValue *fi = index2value(L, fidx); - api_check(L, ttisLclosure(fi), "Lua function expected"); - f = clLvalue(fi); - if (pf) *pf = f; - if (1 <= n && n <= f->p->sizeupvalues) - return &f->upvals[n - 1]; /* get its upvalue pointer */ - else - return (UpVal**)&nullup; -} - - -LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { - TValue *fi = index2value(L, fidx); - switch (ttypetag(fi)) { - case LUA_VLCL: { /* lua closure */ - return *getupvalref(L, fidx, n, NULL); - } - case LUA_VCCL: { /* C closure */ - CClosure *f = clCvalue(fi); - if (1 <= n && n <= f->nupvalues) - return &f->upvalue[n - 1]; - /* else */ - } /* FALLTHROUGH */ - case LUA_VLCF: - return NULL; /* light C functions have no upvalues */ - default: { - api_check(L, 0, "function expected"); - return NULL; - } - } -} - - -LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, - int fidx2, int n2) { - LClosure *f1; - UpVal **up1 = getupvalref(L, fidx1, n1, &f1); - UpVal **up2 = getupvalref(L, fidx2, n2, NULL); - api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index"); - *up1 = *up2; - luaC_objbarrier(L, f1, *up1); -} - - diff --git a/source/external/lua/lapi.h b/source/external/lua/lapi.h index 9e99cc4..9b54534 100644 --- a/source/external/lua/lapi.h +++ b/source/external/lua/lapi.h @@ -12,38 +12,54 @@ #include "lstate.h" -/* Increments 'L->top', checking for stack overflows */ -#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ - "stack overflow");} +#if defined(LUA_USE_APICHECK) +#include +#define api_check(l,e,msg) assert(e) +#else /* for testing */ +#define api_check(l,e,msg) ((void)(l), lua_assert((e) && msg)) +#endif + + + +/* Increments 'L->top.p', checking for stack overflows */ +#define api_incr_top(L) \ + (L->top.p++, api_check(L, L->top.p <= L->ci->top.p, "stack overflow")) + + +/* +** macros that are executed whenever 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 + /* ** If a call returns too many multiple returns, the callee may not have ** stack space to accommodate all results. In this case, this macro -** increases its stack space ('L->ci->top'). +** increases its stack space ('L->ci->top.p'). */ #define adjustresults(L,nres) \ - { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } + { if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \ + L->ci->top.p = L->top.p; } /* Ensure the stack has at least 'n' elements */ -#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ - "not enough elements in the stack") +#define api_checknelems(L,n) \ + api_check(L, (n) < (L->top.p - L->ci->func.p), \ + "not enough elements in the stack") -/* -** To reduce the overhead of returning from C functions, the presence of -** to-be-closed variables in these functions is coded in the CallInfo's -** field 'nresults', in a way that functions with no to-be-closed variables -** with zero, one, or "all" wanted results have no overhead. Functions -** with other number of wanted results, as well as functions with -** variables to be closed, have an extra check. +/* Ensure the stack has at least 'n' elements to be popped. (Some +** functions only update a slot after checking it for popping, but that +** is only an optimization for a pop followed by a push.) */ - -#define hastocloseCfunc(n) ((n) < LUA_MULTRET) - -/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ -#define codeNresults(n) (-(n) - 3) -#define decodeNresults(n) (-(n) - 3) +#define api_checkpop(L,n) \ + api_check(L, (n) < L->top.p - L->ci->func.p && \ + L->tbclist.p < L->top.p - (n), \ + "not enough free elements in the stack") #endif diff --git a/source/external/lua/lauxlib.c b/source/external/lua/lauxlib.c deleted file mode 100644 index 94835ef..0000000 --- a/source/external/lua/lauxlib.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* -** $Id: lauxlib.c $ -** Auxiliary functions for building Lua libraries -** See Copyright Notice in lua.h -*/ - -#define lauxlib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include -#include -#include - - -/* -** This file uses only the official API of Lua. -** Any function declared here could be written as an application function. -*/ - -#include "lua.h" - -#include "lauxlib.h" - - -#if !defined(MAX_SIZET) -/* maximum value for size_t */ -#define MAX_SIZET ((size_t)(~(size_t)0)) -#endif - - -/* -** {====================================================== -** Traceback -** ======================================================= -*/ - - -#define LEVELS1 10 /* size of the first part of the stack */ -#define LEVELS2 11 /* size of the second part of the stack */ - - - -/* -** Search for 'objidx' in table at index -1. ('objidx' must be an -** absolute index.) Return 1 + string at top if it found a good name. -*/ -static int findfield (lua_State *L, int objidx, int level) { - if (level == 0 || !lua_istable(L, -1)) - return 0; /* not found */ - lua_pushnil(L); /* start 'next' loop */ - while (lua_next(L, -2)) { /* for each pair in table */ - if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ - if (lua_rawequal(L, objidx, -1)) { /* found object? */ - lua_pop(L, 1); /* remove value (but keep name) */ - return 1; - } - else if (findfield(L, objidx, level - 1)) { /* try recursively */ - /* stack: lib_name, lib_table, field_name (top) */ - lua_pushliteral(L, "."); /* place '.' between the two names */ - lua_replace(L, -3); /* (in the slot occupied by table) */ - lua_concat(L, 3); /* lib_name.field_name */ - return 1; - } - } - lua_pop(L, 1); /* remove value */ - } - return 0; /* not found */ -} - - -/* -** Search for a name for a function in all loaded modules -*/ -static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { - int top = lua_gettop(L); - lua_getinfo(L, "f", ar); /* push function */ - lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); - if (findfield(L, top + 1, 2)) { - const char *name = lua_tostring(L, -1); - if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */ - lua_pushstring(L, name + 3); /* push name without prefix */ - lua_remove(L, -2); /* remove original name */ - } - lua_copy(L, -1, top + 1); /* copy name to proper place */ - lua_settop(L, top + 1); /* remove table "loaded" and name copy */ - return 1; - } - else { - lua_settop(L, top); /* remove function and global table */ - return 0; - } -} - - -static void pushfuncname (lua_State *L, lua_Debug *ar) { - if (pushglobalfuncname(L, ar)) { /* try first a global name */ - lua_pushfstring(L, "function '%s'", lua_tostring(L, -1)); - lua_remove(L, -2); /* remove name */ - } - else if (*ar->namewhat != '\0') /* is there a name from code? */ - lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name); /* use it */ - else if (*ar->what == 'm') /* main? */ - lua_pushliteral(L, "main chunk"); - else if (*ar->what != 'C') /* for Lua functions, use */ - lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); - else /* nothing left... */ - lua_pushliteral(L, "?"); -} - - -static int lastlevel (lua_State *L) { - lua_Debug ar; - int li = 1, le = 1; - /* find an upper bound */ - while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } - /* do a binary search */ - while (li < le) { - int m = (li + le)/2; - if (lua_getstack(L, m, &ar)) li = m + 1; - else le = m; - } - return le - 1; -} - - -LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, - const char *msg, int level) { - luaL_Buffer b; - lua_Debug ar; - int last = lastlevel(L1); - int limit2show = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; - luaL_buffinit(L, &b); - if (msg) { - luaL_addstring(&b, msg); - luaL_addchar(&b, '\n'); - } - luaL_addstring(&b, "stack traceback:"); - while (lua_getstack(L1, level++, &ar)) { - if (limit2show-- == 0) { /* too many levels? */ - int n = last - level - LEVELS2 + 1; /* number of levels to skip */ - lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n); - luaL_addvalue(&b); /* add warning about skip */ - level += n; /* and skip to last levels */ - } - else { - lua_getinfo(L1, "Slnt", &ar); - if (ar.currentline <= 0) - lua_pushfstring(L, "\n\t%s: in ", ar.short_src); - else - lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline); - luaL_addvalue(&b); - pushfuncname(L, &ar); - luaL_addvalue(&b); - if (ar.istailcall) - luaL_addstring(&b, "\n\t(...tail calls...)"); - } - } - luaL_pushresult(&b); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Error-report functions -** ======================================================= -*/ - -LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { - lua_Debug ar; - if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ - return luaL_error(L, "bad argument #%d (%s)", arg, extramsg); - lua_getinfo(L, "n", &ar); - if (strcmp(ar.namewhat, "method") == 0) { - arg--; /* do not count 'self' */ - if (arg == 0) /* error is in the self argument itself? */ - return luaL_error(L, "calling '%s' on bad self (%s)", - ar.name, extramsg); - } - if (ar.name == NULL) - ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; - return luaL_error(L, "bad argument #%d to '%s' (%s)", - arg, ar.name, extramsg); -} - - -LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) { - const char *msg; - const char *typearg; /* name for the type of the actual argument */ - if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) - typearg = lua_tostring(L, -1); /* use the given type name */ - else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA) - typearg = "light userdata"; /* special name for messages */ - else - typearg = luaL_typename(L, arg); /* standard name */ - msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg); - return luaL_argerror(L, arg, msg); -} - - -static void tag_error (lua_State *L, int arg, int tag) { - luaL_typeerror(L, arg, lua_typename(L, tag)); -} - - -/* -** The use of 'lua_pushfstring' ensures this function does not -** need reserved stack space when called. -*/ -LUALIB_API void luaL_where (lua_State *L, int level) { - lua_Debug ar; - if (lua_getstack(L, level, &ar)) { /* check function at level */ - lua_getinfo(L, "Sl", &ar); /* get info about it */ - if (ar.currentline > 0) { /* is there info? */ - lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); - return; - } - } - lua_pushfstring(L, ""); /* else, no information available... */ -} - - -/* -** Again, the use of 'lua_pushvfstring' ensures this function does -** not need reserved stack space when called. (At worst, it generates -** an error with "stack overflow" instead of the given message.) -*/ -LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - luaL_where(L, 1); - lua_pushvfstring(L, fmt, argp); - va_end(argp); - lua_concat(L, 2); - return lua_error(L); -} - - -LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { - int en = errno; /* calls to Lua API may change this value */ - if (stat) { - lua_pushboolean(L, 1); - return 1; - } - else { - luaL_pushfail(L); - if (fname) - lua_pushfstring(L, "%s: %s", fname, strerror(en)); - else - lua_pushstring(L, strerror(en)); - lua_pushinteger(L, en); - return 3; - } -} - - -#if !defined(l_inspectstat) /* { */ - -#if defined(LUA_USE_POSIX) - -#include - -/* -** use appropriate macros to interpret 'pclose' return status -*/ -#define l_inspectstat(stat,what) \ - if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ - else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } - -#else - -#define l_inspectstat(stat,what) /* no op */ - -#endif - -#endif /* } */ - - -LUALIB_API int luaL_execresult (lua_State *L, int stat) { - if (stat != 0 && errno != 0) /* error with an 'errno'? */ - return luaL_fileresult(L, 0, NULL); - else { - const char *what = "exit"; /* type of termination */ - l_inspectstat(stat, what); /* interpret result */ - if (*what == 'e' && stat == 0) /* successful termination? */ - lua_pushboolean(L, 1); - else - luaL_pushfail(L); - lua_pushstring(L, what); - lua_pushinteger(L, stat); - return 3; /* return true/fail,what,code */ - } -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** Userdata's metatable manipulation -** ======================================================= -*/ - -LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { - 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_createtable(L, 0, 2); /* create metatable */ - lua_pushstring(L, tname); - lua_setfield(L, -2, "__name"); /* metatable.__name = tname */ - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ - return 1; -} - - -LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { - luaL_getmetatable(L, tname); - lua_setmetatable(L, -2); -} - - -LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { - void *p = lua_touserdata(L, ud); - if (p != NULL) { /* value is a userdata? */ - if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ - luaL_getmetatable(L, tname); /* get correct metatable */ - if (!lua_rawequal(L, -1, -2)) /* not the same? */ - p = NULL; /* value is a userdata with wrong metatable */ - lua_pop(L, 2); /* remove both metatables */ - return p; - } - } - return NULL; /* value is not a userdata with a metatable */ -} - - -LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { - void *p = luaL_testudata(L, ud, tname); - luaL_argexpected(L, p != NULL, ud, tname); - return p; -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Argument check functions -** ======================================================= -*/ - -LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, - const char *const lst[]) { - const char *name = (def) ? luaL_optstring(L, arg, def) : - luaL_checkstring(L, arg); - int i; - for (i=0; lst[i]; i++) - if (strcmp(lst[i], name) == 0) - return i; - return luaL_argerror(L, arg, - lua_pushfstring(L, "invalid option '%s'", name)); -} - - -/* -** Ensures the stack has at least 'space' extra slots, raising an error -** if it cannot fulfill the request. (The error handling needs a few -** extra slots to format the error message. In case of an error without -** this extra space, Lua will generate the same 'stack overflow' error, -** but without 'msg'.) -*/ -LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { - if (l_unlikely(!lua_checkstack(L, space))) { - if (msg) - luaL_error(L, "stack overflow (%s)", msg); - else - luaL_error(L, "stack overflow"); - } -} - - -LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) { - if (l_unlikely(lua_type(L, arg) != t)) - tag_error(L, arg, t); -} - - -LUALIB_API void luaL_checkany (lua_State *L, int arg) { - if (l_unlikely(lua_type(L, arg) == LUA_TNONE)) - luaL_argerror(L, arg, "value expected"); -} - - -LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) { - const char *s = lua_tolstring(L, arg, len); - if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING); - return s; -} - - -LUALIB_API const char *luaL_optlstring (lua_State *L, int arg, - const char *def, size_t *len) { - if (lua_isnoneornil(L, arg)) { - if (len) - *len = (def ? strlen(def) : 0); - return def; - } - else return luaL_checklstring(L, arg, len); -} - - -LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) { - int isnum; - lua_Number d = lua_tonumberx(L, arg, &isnum); - if (l_unlikely(!isnum)) - tag_error(L, arg, LUA_TNUMBER); - return d; -} - - -LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) { - return luaL_opt(L, luaL_checknumber, arg, def); -} - - -static void interror (lua_State *L, int arg) { - if (lua_isnumber(L, arg)) - luaL_argerror(L, arg, "number has no integer representation"); - else - tag_error(L, arg, LUA_TNUMBER); -} - - -LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) { - int isnum; - lua_Integer d = lua_tointegerx(L, arg, &isnum); - if (l_unlikely(!isnum)) { - interror(L, arg); - } - return d; -} - - -LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg, - lua_Integer def) { - return luaL_opt(L, luaL_checkinteger, arg, def); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Generic Buffer manipulation -** ======================================================= -*/ - -/* userdata to box arbitrary data */ -typedef struct UBox { - void *box; - size_t bsize; -} UBox; - - -static void *resizebox (lua_State *L, int idx, size_t newsize) { - void *ud; - lua_Alloc allocf = lua_getallocf(L, &ud); - UBox *box = (UBox *)lua_touserdata(L, idx); - void *temp = allocf(ud, box->box, box->bsize, newsize); - if (l_unlikely(temp == NULL && newsize > 0)) { /* allocation error? */ - lua_pushliteral(L, "not enough memory"); - lua_error(L); /* raise a memory error */ - } - box->box = temp; - box->bsize = newsize; - return temp; -} - - -static int boxgc (lua_State *L) { - resizebox(L, 1, 0); - return 0; -} - - -static const luaL_Reg boxmt[] = { /* box metamethods */ - {"__gc", boxgc}, - {"__close", boxgc}, - {NULL, NULL} -}; - - -static void newbox (lua_State *L) { - UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); - box->box = NULL; - box->bsize = 0; - if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ - luaL_setfuncs(L, boxmt, 0); /* set its metamethods */ - lua_setmetatable(L, -2); -} - - -/* -** check whether buffer is using a userdata on the stack as a temporary -** buffer -*/ -#define buffonstack(B) ((B)->b != (B)->init.b) - - -/* -** Whenever buffer is accessed, slot 'idx' must either be a box (which -** cannot be NULL) or it is a placeholder for the buffer. -*/ -#define checkbufferlevel(B,idx) \ - lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \ - : lua_touserdata(B->L, idx) == (void*)B) - - -/* -** Compute new size for buffer 'B', enough to accommodate extra 'sz' -** bytes. -*/ -static size_t newbuffsize (luaL_Buffer *B, size_t sz) { - size_t newsize = B->size * 2; /* double buffer size */ - if (l_unlikely(MAX_SIZET - sz < B->n)) /* overflow in (B->n + sz)? */ - return luaL_error(B->L, "buffer too large"); - if (newsize < B->n + sz) /* double is not big enough? */ - newsize = B->n + sz; - return newsize; -} - - -/* -** Returns a pointer to a free area with at least 'sz' bytes in buffer -** 'B'. 'boxidx' is the relative position in the stack where is the -** buffer's box or its placeholder. -*/ -static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) { - checkbufferlevel(B, boxidx); - if (B->size - B->n >= sz) /* enough space? */ - return B->b + B->n; - else { - lua_State *L = B->L; - char *newbuff; - size_t newsize = newbuffsize(B, sz); - /* create larger buffer */ - if (buffonstack(B)) /* buffer already has a box? */ - newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */ - else { /* no box yet */ - lua_remove(L, boxidx); /* remove placeholder */ - newbox(L); /* create a new box */ - lua_insert(L, boxidx); /* move box to its intended position */ - lua_toclose(L, boxidx); - newbuff = (char *)resizebox(L, boxidx, newsize); - memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ - } - B->b = newbuff; - B->size = newsize; - return newbuff + B->n; - } -} - -/* -** returns a pointer to a free area with at least 'sz' bytes -*/ -LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { - return prepbuffsize(B, sz, -1); -} - - -LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { - if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ - char *b = prepbuffsize(B, l, -1); - memcpy(b, s, l * sizeof(char)); - luaL_addsize(B, l); - } -} - - -LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { - luaL_addlstring(B, s, strlen(s)); -} - - -LUALIB_API void luaL_pushresult (luaL_Buffer *B) { - lua_State *L = B->L; - checkbufferlevel(B, -1); - lua_pushlstring(L, B->b, B->n); - if (buffonstack(B)) - lua_closeslot(L, -2); /* close the box */ - lua_remove(L, -2); /* remove box or placeholder from the stack */ -} - - -LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { - luaL_addsize(B, sz); - luaL_pushresult(B); -} - - -/* -** 'luaL_addvalue' is the only function in the Buffer system where the -** box (if existent) is not on the top of the stack. So, instead of -** calling 'luaL_addlstring', it replicates the code using -2 as the -** last argument to 'prepbuffsize', signaling that the box is (or will -** be) bellow the string being added to the buffer. (Box creation can -** trigger an emergency GC, so we should not remove the string from the -** stack before we have the space guaranteed.) -*/ -LUALIB_API void luaL_addvalue (luaL_Buffer *B) { - lua_State *L = B->L; - size_t len; - const char *s = lua_tolstring(L, -1, &len); - char *b = prepbuffsize(B, len, -2); - memcpy(b, s, len * sizeof(char)); - luaL_addsize(B, len); - lua_pop(L, 1); /* pop string */ -} - - -LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { - B->L = L; - B->b = B->init.b; - B->n = 0; - B->size = LUAL_BUFFERSIZE; - lua_pushlightuserdata(L, (void*)B); /* push placeholder */ -} - - -LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { - luaL_buffinit(L, B); - return prepbuffsize(B, sz, -1); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Reference system -** ======================================================= -*/ - -/* index of free-list header (after the predefined values) */ -#define freelist (LUA_RIDX_LAST + 1) - -/* -** The previously freed references form a linked list: -** t[freelist] is the index of a first free index, or zero if list is -** empty; t[t[freelist]] is the index of the second element; etc. -*/ -LUALIB_API int luaL_ref (lua_State *L, int t) { - int ref; - if (lua_isnil(L, -1)) { - lua_pop(L, 1); /* remove from stack */ - return LUA_REFNIL; /* 'nil' has a unique fixed reference */ - } - t = lua_absindex(L, t); - if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */ - ref = 0; /* list is empty */ - lua_pushinteger(L, 0); /* initialize as an empty list */ - lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */ - } - else { /* already initialized */ - lua_assert(lua_isinteger(L, -1)); - ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ - } - lua_pop(L, 1); /* remove element from stack */ - if (ref != 0) { /* any free element? */ - lua_rawgeti(L, t, ref); /* remove it from list */ - lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ - } - else /* no free elements */ - ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ - lua_rawseti(L, t, ref); - return ref; -} - - -LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { - if (ref >= 0) { - t = lua_absindex(L, t); - lua_rawgeti(L, t, freelist); - lua_assert(lua_isinteger(L, -1)); - lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ - lua_pushinteger(L, ref); - lua_rawseti(L, t, freelist); /* t[freelist] = ref */ - } -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Load functions -** ======================================================= -*/ - -typedef struct LoadF { - int n; /* number of pre-read characters */ - FILE *f; /* file being read */ - char buff[BUFSIZ]; /* area for reading file */ -} LoadF; - - -static const char *getF (lua_State *L, void *ud, size_t *size) { - LoadF *lf = (LoadF *)ud; - (void)L; /* not used */ - if (lf->n > 0) { /* are there pre-read characters to be read? */ - *size = lf->n; /* return them (chars already in buffer) */ - lf->n = 0; /* no more pre-read characters */ - } - else { /* read a block from file */ - /* 'fread' can return > 0 *and* set the EOF flag. If next call to - 'getF' called 'fread', it might still wait for user input. - The next check avoids this problem. */ - if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ - } - return lf->buff; -} - - -static int errfile (lua_State *L, const char *what, int fnameindex) { - const char *serr = strerror(errno); - const char *filename = lua_tostring(L, fnameindex) + 1; - lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); - lua_remove(L, fnameindex); - return LUA_ERRFILE; -} - - -static int skipBOM (LoadF *lf) { - const char *p = "\xEF\xBB\xBF"; /* UTF-8 BOM mark */ - int c; - lf->n = 0; - do { - c = getc(lf->f); - if (c == EOF || c != *(const unsigned char *)p++) return c; - lf->buff[lf->n++] = c; /* to be read by the parser */ - } while (*p != '\0'); - lf->n = 0; /* prefix matched; discard it */ - return getc(lf->f); /* return next character */ -} - - -/* -** reads the first character of file 'f' and skips an optional BOM mark -** in its beginning plus its first line if it starts with '#'. Returns -** true if it skipped the first line. In any case, '*cp' has the -** first "valid" character of the file (after the optional BOM and -** a first-line comment). -*/ -static int skipcomment (LoadF *lf, int *cp) { - int c = *cp = skipBOM(lf); - if (c == '#') { /* first line is a comment (Unix exec. file)? */ - do { /* skip first line */ - c = getc(lf->f); - } while (c != EOF && c != '\n'); - *cp = getc(lf->f); /* skip end-of-line, if present */ - return 1; /* there was a comment */ - } - else return 0; /* no comment */ -} - - -LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, - const char *mode) { - LoadF lf; - int status, readstatus; - int c; - int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ - if (filename == NULL) { - lua_pushliteral(L, "=stdin"); - lf.f = stdin; - } - else { - lua_pushfstring(L, "@%s", filename); - lf.f = fopen(filename, "r"); - if (lf.f == NULL) return errfile(L, "open", fnameindex); - } - if (skipcomment(&lf, &c)) /* read initial portion */ - lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ - if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ - lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ - if (lf.f == NULL) return errfile(L, "reopen", fnameindex); - skipcomment(&lf, &c); /* re-read initial portion */ - } - if (c != EOF) - lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ - status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); - readstatus = ferror(lf.f); - if (filename) fclose(lf.f); /* close file (even in case of errors) */ - if (readstatus) { - lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ - return errfile(L, "read", fnameindex); - } - lua_remove(L, fnameindex); - return status; -} - - -typedef struct LoadS { - const char *s; - size_t size; -} LoadS; - - -static const char *getS (lua_State *L, void *ud, size_t *size) { - LoadS *ls = (LoadS *)ud; - (void)L; /* not used */ - if (ls->size == 0) return NULL; - *size = ls->size; - ls->size = 0; - return ls->s; -} - - -LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, - const char *name, const char *mode) { - LoadS ls; - ls.s = buff; - ls.size = size; - return lua_load(L, getS, &ls, name, mode); -} - - -LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { - return luaL_loadbuffer(L, s, strlen(s), s); -} - -/* }====================================================== */ - - - -LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { - if (!lua_getmetatable(L, obj)) /* no metatable? */ - return LUA_TNIL; - else { - int tt; - lua_pushstring(L, event); - tt = lua_rawget(L, -2); - if (tt == LUA_TNIL) /* is metafield nil? */ - lua_pop(L, 2); /* remove metatable and metafield */ - else - lua_remove(L, -2); /* remove only metatable */ - return tt; /* return metafield type */ - } -} - - -LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { - obj = lua_absindex(L, obj); - if (luaL_getmetafield(L, obj, event) == LUA_TNIL) /* no metafield? */ - return 0; - lua_pushvalue(L, obj); - lua_call(L, 1, 1); - return 1; -} - - -LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { - lua_Integer l; - int isnum; - lua_len(L, idx); - l = lua_tointegerx(L, -1, &isnum); - if (l_unlikely(!isnum)) - luaL_error(L, "object length is not an integer"); - lua_pop(L, 1); /* remove object */ - return l; -} - - -LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { - if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ - if (!lua_isstring(L, -1)) - luaL_error(L, "'__tostring' must return a string"); - } - else { - switch (lua_type(L, idx)) { - case LUA_TNUMBER: { - if (lua_isinteger(L, idx)) - lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx)); - else - lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx)); - break; - } - case LUA_TSTRING: - lua_pushvalue(L, idx); - break; - case LUA_TBOOLEAN: - lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); - break; - case LUA_TNIL: - lua_pushliteral(L, "nil"); - break; - default: { - int tt = luaL_getmetafield(L, idx, "__name"); /* try name */ - const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : - luaL_typename(L, idx); - lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx)); - if (tt != LUA_TNIL) - lua_remove(L, -2); /* remove '__name' */ - break; - } - } - } - return lua_tolstring(L, -1, len); -} - - -/* -** set functions from list 'l' into table at top - 'nup'; each -** function gets the 'nup' elements at the top as upvalues. -** Returns with only the table at the stack. -*/ -LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { - luaL_checkstack(L, nup, "too many upvalues"); - for (; l->name != NULL; l++) { /* fill the table with given functions */ - if (l->func == NULL) /* place holder? */ - lua_pushboolean(L, 0); - else { - int i; - for (i = 0; i < nup; i++) /* copy upvalues to the top */ - lua_pushvalue(L, -nup); - lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ - } - lua_setfield(L, -(nup + 2), l->name); - } - lua_pop(L, nup); /* remove upvalues */ -} - - -/* -** ensure that stack[idx][fname] has a table and push that table -** into the stack -*/ -LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { - if (lua_getfield(L, idx, fname) == LUA_TTABLE) - return 1; /* table already there */ - else { - lua_pop(L, 1); /* remove previous result */ - idx = lua_absindex(L, idx); - lua_newtable(L); - lua_pushvalue(L, -1); /* copy to be left at top */ - lua_setfield(L, idx, fname); /* assign new table to field */ - return 0; /* false, because did not find table there */ - } -} - - -/* -** Stripped-down 'require': After checking "loaded" table, calls 'openf' -** to open a module, registers the result in 'package.loaded' table and, -** if 'glb' is true, also registers the result in the global table. -** Leaves resulting module on the top. -*/ -LUALIB_API void luaL_requiref (lua_State *L, const char *modname, - lua_CFunction openf, int glb) { - luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); - lua_getfield(L, -1, modname); /* LOADED[modname] */ - if (!lua_toboolean(L, -1)) { /* package not already loaded? */ - lua_pop(L, 1); /* remove field */ - lua_pushcfunction(L, openf); - lua_pushstring(L, modname); /* argument to open function */ - lua_call(L, 1, 1); /* call 'openf' to open module */ - lua_pushvalue(L, -1); /* make copy of module (call result) */ - lua_setfield(L, -3, modname); /* LOADED[modname] = module */ - } - lua_remove(L, -2); /* remove LOADED table */ - if (glb) { - lua_pushvalue(L, -1); /* copy of module */ - lua_setglobal(L, modname); /* _G[modname] = module */ - } -} - - -LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, - const char *p, const char *r) { - const char *wild; - size_t l = strlen(p); - while ((wild = strstr(s, p)) != NULL) { - luaL_addlstring(b, s, wild - s); /* push prefix */ - luaL_addstring(b, r); /* push replacement in place of pattern */ - s = wild + l; /* continue after 'p' */ - } - luaL_addstring(b, s); /* push last suffix */ -} - - -LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, - const char *p, const char *r) { - luaL_Buffer b; - luaL_buffinit(L, &b); - luaL_addgsub(&b, s, p, r); - luaL_pushresult(&b); - return lua_tostring(L, -1); -} - - -static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { - (void)ud; (void)osize; /* not used */ - if (nsize == 0) { - free(ptr); - return NULL; - } - else - return realloc(ptr, nsize); -} - - -static int panic (lua_State *L) { - const char *msg = lua_tostring(L, -1); - if (msg == NULL) msg = "error object is not a string"; - lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", - msg); - return 0; /* return to Lua to abort */ -} - - -/* -** Warning functions: -** warnfoff: warning system is off -** warnfon: ready to start a new message -** warnfcont: previous message is to be continued -*/ -static void warnfoff (void *ud, const char *message, int tocont); -static void warnfon (void *ud, const char *message, int tocont); -static void warnfcont (void *ud, const char *message, int tocont); - - -/* -** Check whether message is a control message. If so, execute the -** control or ignore it if unknown. -*/ -static int checkcontrol (lua_State *L, const char *message, int tocont) { - if (tocont || *(message++) != '@') /* not a control message? */ - return 0; - else { - if (strcmp(message, "off") == 0) - lua_setwarnf(L, warnfoff, L); /* turn warnings off */ - else if (strcmp(message, "on") == 0) - lua_setwarnf(L, warnfon, L); /* turn warnings on */ - return 1; /* it was a control message */ - } -} - - -static void warnfoff (void *ud, const char *message, int tocont) { - checkcontrol((lua_State *)ud, message, tocont); -} - - -/* -** Writes the message and handle 'tocont', finishing the message -** if needed and setting the next warn function. -*/ -static void warnfcont (void *ud, const char *message, int tocont) { - lua_State *L = (lua_State *)ud; - lua_writestringerror("%s", message); /* write message */ - if (tocont) /* not the last part? */ - lua_setwarnf(L, warnfcont, L); /* to be continued */ - else { /* last part */ - lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ - lua_setwarnf(L, warnfon, L); /* next call is a new message */ - } -} - - -static void warnfon (void *ud, const char *message, int tocont) { - if (checkcontrol((lua_State *)ud, message, tocont)) /* control message? */ - return; /* nothing else to be done */ - lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ - warnfcont(ud, message, tocont); /* finish processing */ -} - - -LUALIB_API lua_State *luaL_newstate (void) { - lua_State *L = lua_newstate(l_alloc, NULL); - if (l_likely(L)) { - lua_atpanic(L, &panic); - lua_setwarnf(L, warnfoff, L); /* default is warnings off */ - } - return L; -} - - -LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { - lua_Number v = lua_version(L); - if (sz != LUAL_NUMSIZES) /* check numeric types */ - luaL_error(L, "core and library have incompatible numeric types"); - else if (v != ver) - luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", - (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)v); -} - diff --git a/source/external/lua/lauxlib.h b/source/external/lua/lauxlib.h index 72f70e7..7f1d3ca 100644 --- a/source/external/lua/lauxlib.h +++ b/source/external/lua/lauxlib.h @@ -81,6 +81,9 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); LUALIB_API int (luaL_execresult) (lua_State *L, int stat); +LUALIB_API void *luaL_alloc (void *ud, void *ptr, size_t osize, + size_t nsize); + /* predefined references */ #define LUA_NOREF (-2) @@ -100,9 +103,11 @@ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); LUALIB_API lua_State *(luaL_newstate) (void); +LUALIB_API unsigned luaL_makeseed (lua_State *L); + LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); -LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, +LUALIB_API void (luaL_addgsub) (luaL_Buffer *b, const char *s, const char *p, const char *r); LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r); @@ -154,22 +159,19 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) -/* push the value used to represent failure/error */ -#define luaL_pushfail(L) lua_pushnil(L) - - /* -** Internal assertions for in-house debugging +** Perform arithmetic operations on lua_Integer values with wrap-around +** semantics, as the Lua core does. */ -#if !defined(lua_assert) +#define luaL_intop(op,v1,v2) \ + ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) -#if defined LUAI_ASSERT - #include - #define lua_assert(c) assert(c) + +/* push the value used to represent failure/error */ +#if defined(LUA_FAILISFALSE) +#define luaL_pushfail(L) lua_pushboolean(L, 0) #else - #define lua_assert(c) ((void)0) -#endif - +#define luaL_pushfail(L) lua_pushnil(L) #endif @@ -241,30 +243,6 @@ typedef struct luaL_Stream { /* }====================================================== */ -/* -** {================================================================== -** "Abstraction Layer" for basic report of messages and errors -** =================================================================== -*/ - -/* print a string */ -#if !defined(lua_writestring) -#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) -#endif - -/* print a newline and flush the output */ -#if !defined(lua_writeline) -#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) -#endif - -/* print an error message */ -#if !defined(lua_writestringerror) -#define lua_writestringerror(s,p) \ - (fprintf(stderr, (s), (p)), fflush(stderr)) -#endif - -/* }================================================================== */ - /* ** {============================================================ diff --git a/source/external/lua/lbaselib.c b/source/external/lua/lbaselib.c deleted file mode 100644 index 83ad306..0000000 --- a/source/external/lua/lbaselib.c +++ /dev/null @@ -1,528 +0,0 @@ -/* -** $Id: lbaselib.c $ -** Basic library -** See Copyright Notice in lua.h -*/ - -#define lbaselib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -static int luaB_print (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - for (i = 1; i <= n; i++) { /* for each argument */ - size_t l; - const char *s = luaL_tolstring(L, i, &l); /* convert it to string */ - if (i > 1) /* not the first element? */ - lua_writestring("\t", 1); /* add a tab before it */ - lua_writestring(s, l); /* print it */ - lua_pop(L, 1); /* pop result */ - } - lua_writeline(); - return 0; -} - - -/* -** Creates a warning with all given arguments. -** Check first for errors; otherwise an error may interrupt -** the composition of a warning, leaving it unfinished. -*/ -static int luaB_warn (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - luaL_checkstring(L, 1); /* at least one argument */ - for (i = 2; i <= n; i++) - luaL_checkstring(L, i); /* make sure all arguments are strings */ - for (i = 1; i < n; i++) /* compose warning */ - lua_warning(L, lua_tostring(L, i), 1); - lua_warning(L, lua_tostring(L, n), 0); /* close warning */ - return 0; -} - - -#define SPACECHARS " \f\n\r\t\v" - -static const char *b_str2int (const char *s, int base, lua_Integer *pn) { - lua_Unsigned n = 0; - int neg = 0; - s += strspn(s, SPACECHARS); /* skip initial spaces */ - if (*s == '-') { s++; neg = 1; } /* handle sign */ - else if (*s == '+') s++; - if (!isalnum((unsigned char)*s)) /* no digit? */ - return NULL; - do { - int digit = (isdigit((unsigned char)*s)) ? *s - '0' - : (toupper((unsigned char)*s) - 'A') + 10; - if (digit >= base) return NULL; /* invalid numeral */ - n = n * base + digit; - s++; - } while (isalnum((unsigned char)*s)); - s += strspn(s, SPACECHARS); /* skip trailing spaces */ - *pn = (lua_Integer)((neg) ? (0u - n) : n); - return s; -} - - -static int luaB_tonumber (lua_State *L) { - if (lua_isnoneornil(L, 2)) { /* standard conversion? */ - if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */ - lua_settop(L, 1); /* yes; return it */ - return 1; - } - else { - size_t l; - const char *s = lua_tolstring(L, 1, &l); - if (s != NULL && lua_stringtonumber(L, s) == l + 1) - return 1; /* successful conversion to number */ - /* else not a number */ - luaL_checkany(L, 1); /* (but there must be some parameter) */ - } - } - else { - size_t l; - const char *s; - lua_Integer n = 0; /* to avoid warnings */ - lua_Integer base = luaL_checkinteger(L, 2); - luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */ - s = lua_tolstring(L, 1, &l); - luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); - if (b_str2int(s, (int)base, &n) == s + l) { - lua_pushinteger(L, n); - return 1; - } /* else not a number */ - } /* else not a number */ - luaL_pushfail(L); /* not a number */ - return 1; -} - - -static int luaB_error (lua_State *L) { - int level = (int)luaL_optinteger(L, 2, 1); - lua_settop(L, 1); - if (lua_type(L, 1) == LUA_TSTRING && level > 0) { - luaL_where(L, level); /* add extra information */ - lua_pushvalue(L, 1); - lua_concat(L, 2); - } - return lua_error(L); -} - - -static int luaB_getmetatable (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_getmetatable(L, 1)) { - lua_pushnil(L); - return 1; /* no metatable */ - } - luaL_getmetafield(L, 1, "__metatable"); - return 1; /* returns either __metatable field (if present) or metatable */ -} - - -static int luaB_setmetatable (lua_State *L) { - int t = lua_type(L, 2); - luaL_checktype(L, 1, LUA_TTABLE); - luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); - if (l_unlikely(luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)) - return luaL_error(L, "cannot change a protected metatable"); - lua_settop(L, 2); - lua_setmetatable(L, 1); - return 1; -} - - -static int luaB_rawequal (lua_State *L) { - luaL_checkany(L, 1); - luaL_checkany(L, 2); - lua_pushboolean(L, lua_rawequal(L, 1, 2)); - return 1; -} - - -static int luaB_rawlen (lua_State *L) { - int t = lua_type(L, 1); - luaL_argexpected(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, - "table or string"); - lua_pushinteger(L, lua_rawlen(L, 1)); - return 1; -} - - -static int luaB_rawget (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkany(L, 2); - lua_settop(L, 2); - lua_rawget(L, 1); - return 1; -} - -static int luaB_rawset (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkany(L, 2); - luaL_checkany(L, 3); - lua_settop(L, 3); - lua_rawset(L, 1); - return 1; -} - - -static int pushmode (lua_State *L, int oldmode) { - lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" - : "generational"); - return 1; -} - - -static int luaB_collectgarbage (lua_State *L) { - static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpause", "setstepmul", - "isrunning", "generational", "incremental", NULL}; - static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, - LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, - LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; - int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; - switch (o) { - case LUA_GCCOUNT: { - int k = lua_gc(L, o); - int b = lua_gc(L, LUA_GCCOUNTB); - lua_pushnumber(L, (lua_Number)k + ((lua_Number)b/1024)); - return 1; - } - case LUA_GCSTEP: { - int step = (int)luaL_optinteger(L, 2, 0); - int res = lua_gc(L, o, step); - lua_pushboolean(L, res); - return 1; - } - case LUA_GCSETPAUSE: - case LUA_GCSETSTEPMUL: { - int p = (int)luaL_optinteger(L, 2, 0); - int previous = lua_gc(L, o, p); - lua_pushinteger(L, previous); - return 1; - } - case LUA_GCISRUNNING: { - int res = lua_gc(L, o); - lua_pushboolean(L, res); - return 1; - } - case LUA_GCGEN: { - int minormul = (int)luaL_optinteger(L, 2, 0); - int majormul = (int)luaL_optinteger(L, 3, 0); - return pushmode(L, lua_gc(L, o, minormul, majormul)); - } - case LUA_GCINC: { - int pause = (int)luaL_optinteger(L, 2, 0); - int stepmul = (int)luaL_optinteger(L, 3, 0); - int stepsize = (int)luaL_optinteger(L, 4, 0); - return pushmode(L, lua_gc(L, o, pause, stepmul, stepsize)); - } - default: { - int res = lua_gc(L, o); - lua_pushinteger(L, res); - return 1; - } - } -} - - -static int luaB_type (lua_State *L) { - int t = lua_type(L, 1); - luaL_argcheck(L, t != LUA_TNONE, 1, "value expected"); - lua_pushstring(L, lua_typename(L, t)); - return 1; -} - - -static int luaB_next (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 2); /* create a 2nd argument if there isn't one */ - if (lua_next(L, 1)) - return 2; - else { - lua_pushnil(L); - return 1; - } -} - - -static int luaB_pairs (lua_State *L) { - luaL_checkany(L, 1); - if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */ - lua_pushcfunction(L, luaB_next); /* will return generator, */ - lua_pushvalue(L, 1); /* state, */ - lua_pushnil(L); /* and initial value */ - } - else { - lua_pushvalue(L, 1); /* argument 'self' to metamethod */ - lua_call(L, 1, 3); /* get 3 values from metamethod */ - } - return 3; -} - - -/* -** Traversal function for 'ipairs' -*/ -static int ipairsaux (lua_State *L) { - lua_Integer i = luaL_checkinteger(L, 2) + 1; - lua_pushinteger(L, i); - return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; -} - - -/* -** 'ipairs' function. Returns 'ipairsaux', given "table", 0. -** (The given "table" may not be a table.) -*/ -static int luaB_ipairs (lua_State *L) { - luaL_checkany(L, 1); - lua_pushcfunction(L, ipairsaux); /* iteration function */ - lua_pushvalue(L, 1); /* state */ - lua_pushinteger(L, 0); /* initial value */ - return 3; -} - - -static int load_aux (lua_State *L, int status, int envidx) { - if (l_likely(status == LUA_OK)) { - if (envidx != 0) { /* 'env' parameter? */ - lua_pushvalue(L, envidx); /* environment for loaded function */ - if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ - lua_pop(L, 1); /* remove 'env' if not used by previous call */ - } - return 1; - } - else { /* error (message is on top of the stack) */ - luaL_pushfail(L); - lua_insert(L, -2); /* put before error message */ - return 2; /* return fail plus error message */ - } -} - - -static int luaB_loadfile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); - const char *mode = luaL_optstring(L, 2, NULL); - int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ - int status = luaL_loadfilex(L, fname, mode); - return load_aux(L, status, env); -} - - -/* -** {====================================================== -** Generic Read function -** ======================================================= -*/ - - -/* -** reserved slot, above all arguments, to hold a copy of the returned -** string to avoid it being collected while parsed. 'load' has four -** optional arguments (chunk, source name, mode, and environment). -*/ -#define RESERVEDSLOT 5 - - -/* -** Reader for generic 'load' function: 'lua_load' uses the -** stack for internal stuff, so the reader cannot change the -** stack top. Instead, it keeps its resulting string in a -** reserved slot inside the stack. -*/ -static const char *generic_reader (lua_State *L, void *ud, size_t *size) { - (void)(ud); /* not used */ - luaL_checkstack(L, 2, "too many nested functions"); - lua_pushvalue(L, 1); /* get function */ - lua_call(L, 0, 1); /* call it */ - if (lua_isnil(L, -1)) { - lua_pop(L, 1); /* pop result */ - *size = 0; - return NULL; - } - else if (l_unlikely(!lua_isstring(L, -1))) - luaL_error(L, "reader function must return a string"); - lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ - return lua_tolstring(L, RESERVEDSLOT, size); -} - - -static int luaB_load (lua_State *L) { - int status; - size_t l; - const char *s = lua_tolstring(L, 1, &l); - const char *mode = luaL_optstring(L, 3, "bt"); - int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ - if (s != NULL) { /* loading a string? */ - const char *chunkname = luaL_optstring(L, 2, s); - status = luaL_loadbufferx(L, s, l, chunkname, mode); - } - else { /* loading from a reader function */ - const char *chunkname = luaL_optstring(L, 2, "=(load)"); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, RESERVEDSLOT); /* create reserved slot */ - status = lua_load(L, generic_reader, NULL, chunkname, mode); - } - return load_aux(L, status, env); -} - -/* }====================================================== */ - - -static int dofilecont (lua_State *L, int d1, lua_KContext d2) { - (void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */ - return lua_gettop(L) - 1; -} - - -static int luaB_dofile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); - lua_settop(L, 1); - if (l_unlikely(luaL_loadfile(L, fname) != LUA_OK)) - return lua_error(L); - lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); - return dofilecont(L, 0, 0); -} - - -static int luaB_assert (lua_State *L) { - if (l_likely(lua_toboolean(L, 1))) /* condition is true? */ - return lua_gettop(L); /* return all arguments */ - else { /* error */ - luaL_checkany(L, 1); /* there must be a condition */ - lua_remove(L, 1); /* remove it */ - lua_pushliteral(L, "assertion failed!"); /* default message */ - lua_settop(L, 1); /* leave only message (default if no other one) */ - return luaB_error(L); /* call 'error' */ - } -} - - -static int luaB_select (lua_State *L) { - int n = lua_gettop(L); - if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { - lua_pushinteger(L, n-1); - return 1; - } - else { - lua_Integer i = luaL_checkinteger(L, 1); - if (i < 0) i = n + i; - else if (i > n) i = n; - luaL_argcheck(L, 1 <= i, 1, "index out of range"); - return n - (int)i; - } -} - - -/* -** Continuation function for 'pcall' and 'xpcall'. Both functions -** already pushed a 'true' before doing the call, so in case of success -** 'finishpcall' only has to return everything in the stack minus -** 'extra' values (where 'extra' is exactly the number of items to be -** ignored). -*/ -static int finishpcall (lua_State *L, int status, lua_KContext extra) { - if (l_unlikely(status != LUA_OK && status != LUA_YIELD)) { /* error? */ - lua_pushboolean(L, 0); /* first result (false) */ - lua_pushvalue(L, -2); /* error message */ - return 2; /* return false, msg */ - } - else - return lua_gettop(L) - (int)extra; /* return all results */ -} - - -static int luaB_pcall (lua_State *L) { - int status; - luaL_checkany(L, 1); - lua_pushboolean(L, 1); /* first result if no errors */ - lua_insert(L, 1); /* put it in place */ - status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall); - return finishpcall(L, status, 0); -} - - -/* -** Do a protected call with error handling. After 'lua_rotate', the -** stack will have ; so, the function passes -** 2 to 'finishpcall' to skip the 2 first values when returning results. -*/ -static int luaB_xpcall (lua_State *L) { - int status; - int n = lua_gettop(L); - luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */ - lua_pushboolean(L, 1); /* first result */ - lua_pushvalue(L, 1); /* function */ - lua_rotate(L, 3, 2); /* move them below function's arguments */ - status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall); - return finishpcall(L, status, 2); -} - - -static int luaB_tostring (lua_State *L) { - luaL_checkany(L, 1); - luaL_tolstring(L, 1, NULL); - return 1; -} - - -static const luaL_Reg base_funcs[] = { - {"assert", luaB_assert}, - {"collectgarbage", luaB_collectgarbage}, - {"dofile", luaB_dofile}, - {"error", luaB_error}, - {"getmetatable", luaB_getmetatable}, - {"ipairs", luaB_ipairs}, - {"loadfile", luaB_loadfile}, - {"load", luaB_load}, - {"next", luaB_next}, - {"pairs", luaB_pairs}, - {"pcall", luaB_pcall}, - {"print", luaB_print}, - {"warn", luaB_warn}, - {"rawequal", luaB_rawequal}, - {"rawlen", luaB_rawlen}, - {"rawget", luaB_rawget}, - {"rawset", luaB_rawset}, - {"select", luaB_select}, - {"setmetatable", luaB_setmetatable}, - {"tonumber", luaB_tonumber}, - {"tostring", luaB_tostring}, - {"type", luaB_type}, - {"xpcall", luaB_xpcall}, - /* placeholders */ - {LUA_GNAME, NULL}, - {"_VERSION", NULL}, - {NULL, NULL} -}; - - -LUAMOD_API int luaopen_base (lua_State *L) { - /* open lib into global table */ - lua_pushglobaltable(L); - luaL_setfuncs(L, base_funcs, 0); - /* set global _G */ - lua_pushvalue(L, -1); - lua_setfield(L, -2, LUA_GNAME); - /* set global _VERSION */ - lua_pushliteral(L, LUA_VERSION); - lua_setfield(L, -2, "_VERSION"); - return 1; -} - diff --git a/source/external/lua/lcode.c b/source/external/lua/lcode.c deleted file mode 100644 index 80d975c..0000000 --- a/source/external/lua/lcode.c +++ /dev/null @@ -1,1814 +0,0 @@ -/* -** $Id: lcode.c $ -** Code generator for Lua -** See Copyright Notice in lua.h -*/ - -#define lcode_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include -#include - -#include "lua.h" - -#include "lcode.h" -#include "ldebug.h" -#include "ldo.h" -#include "lgc.h" -#include "llex.h" -#include "lmem.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lparser.h" -#include "lstring.h" -#include "ltable.h" -#include "lvm.h" - - -/* Maximum number of registers in a Lua function (must fit in 8 bits) */ -#define MAXREGS 255 - - -#define hasjumps(e) ((e)->t != (e)->f) - - -static int codesJ (FuncState *fs, OpCode o, int sj, int k); - - - -/* semantic error */ -l_noret luaK_semerror (LexState *ls, const char *msg) { - ls->t.token = 0; /* remove "near " from final message */ - luaX_syntaxerror(ls, msg); -} - - -/* -** If expression is a numeric constant, fills 'v' with its value -** and returns 1. Otherwise, returns 0. -*/ -static int tonumeral (const expdesc *e, TValue *v) { - if (hasjumps(e)) - return 0; /* not a numeral */ - switch (e->k) { - case VKINT: - if (v) setivalue(v, e->u.ival); - return 1; - case VKFLT: - if (v) setfltvalue(v, e->u.nval); - return 1; - default: return 0; - } -} - - -/* -** Get the constant value from a constant expression -*/ -static TValue *const2val (FuncState *fs, const expdesc *e) { - lua_assert(e->k == VCONST); - return &fs->ls->dyd->actvar.arr[e->u.info].k; -} - - -/* -** If expression is a constant, fills 'v' with its value -** and returns 1. Otherwise, returns 0. -*/ -int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) { - if (hasjumps(e)) - return 0; /* not a constant */ - switch (e->k) { - case VFALSE: - setbfvalue(v); - return 1; - case VTRUE: - setbtvalue(v); - return 1; - case VNIL: - setnilvalue(v); - return 1; - case VKSTR: { - setsvalue(fs->ls->L, v, e->u.strval); - return 1; - } - case VCONST: { - setobj(fs->ls->L, v, const2val(fs, e)); - return 1; - } - default: return tonumeral(e, v); - } -} - - -/* -** Return the previous instruction of the current code. If there -** may be a jump target between the current instruction and the -** previous one, return an invalid instruction (to avoid wrong -** optimizations). -*/ -static Instruction *previousinstruction (FuncState *fs) { - static const Instruction invalidinstruction = ~(Instruction)0; - if (fs->pc > fs->lasttarget) - return &fs->f->code[fs->pc - 1]; /* previous instruction */ - else - return cast(Instruction*, &invalidinstruction); -} - - -/* -** Create a OP_LOADNIL instruction, but try to optimize: if the previous -** instruction is also OP_LOADNIL and ranges are compatible, adjust -** range of previous instruction instead of emitting a new one. (For -** instance, 'local a; local b' will generate a single opcode.) -*/ -void luaK_nil (FuncState *fs, int from, int n) { - int l = from + n - 1; /* last register to set nil */ - Instruction *previous = previousinstruction(fs); - if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */ - int pfrom = GETARG_A(*previous); /* get previous range */ - int pl = pfrom + GETARG_B(*previous); - if ((pfrom <= from && from <= pl + 1) || - (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ - if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ - if (pl > l) l = pl; /* l = max(l, pl) */ - SETARG_A(*previous, from); - SETARG_B(*previous, l - from); - return; - } /* else go through */ - } - luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ -} - - -/* -** Gets the destination address of a jump instruction. Used to traverse -** a list of jumps. -*/ -static int getjump (FuncState *fs, int pc) { - int offset = GETARG_sJ(fs->f->code[pc]); - if (offset == NO_JUMP) /* point to itself represents end of list */ - return NO_JUMP; /* end of list */ - else - return (pc+1)+offset; /* turn offset into absolute position */ -} - - -/* -** Fix jump instruction at position 'pc' to jump to 'dest'. -** (Jump addresses are relative in Lua) -*/ -static void fixjump (FuncState *fs, int pc, int dest) { - Instruction *jmp = &fs->f->code[pc]; - int offset = dest - (pc + 1); - lua_assert(dest != NO_JUMP); - if (!(-OFFSET_sJ <= offset && offset <= MAXARG_sJ - OFFSET_sJ)) - luaX_syntaxerror(fs->ls, "control structure too long"); - lua_assert(GET_OPCODE(*jmp) == OP_JMP); - SETARG_sJ(*jmp, offset); -} - - -/* -** Concatenate jump-list 'l2' into jump-list 'l1' -*/ -void luaK_concat (FuncState *fs, int *l1, int l2) { - if (l2 == NO_JUMP) return; /* nothing to concatenate? */ - else if (*l1 == NO_JUMP) /* no original list? */ - *l1 = l2; /* 'l1' points to 'l2' */ - else { - int list = *l1; - int next; - while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ - list = next; - fixjump(fs, list, l2); /* last element links to 'l2' */ - } -} - - -/* -** Create a jump instruction and return its position, so its destination -** can be fixed later (with 'fixjump'). -*/ -int luaK_jump (FuncState *fs) { - return codesJ(fs, OP_JMP, NO_JUMP, 0); -} - - -/* -** Code a 'return' instruction -*/ -void luaK_ret (FuncState *fs, int first, int nret) { - OpCode op; - switch (nret) { - case 0: op = OP_RETURN0; break; - case 1: op = OP_RETURN1; break; - default: op = OP_RETURN; break; - } - luaK_codeABC(fs, op, first, nret + 1, 0); -} - - -/* -** Code a "conditional jump", that is, a test or comparison opcode -** followed by a jump. Return jump position. -*/ -static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) { - luaK_codeABCk(fs, op, A, B, C, k); - return luaK_jump(fs); -} - - -/* -** returns current 'pc' and marks it as a jump target (to avoid wrong -** optimizations with consecutive instructions not in the same basic block). -*/ -int luaK_getlabel (FuncState *fs) { - fs->lasttarget = fs->pc; - return fs->pc; -} - - -/* -** Returns the position of the instruction "controlling" a given -** jump (that is, its condition), or the jump itself if it is -** unconditional. -*/ -static Instruction *getjumpcontrol (FuncState *fs, int pc) { - Instruction *pi = &fs->f->code[pc]; - if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) - return pi-1; - else - return pi; -} - - -/* -** Patch destination register for a TESTSET instruction. -** If instruction in position 'node' is not a TESTSET, return 0 ("fails"). -** Otherwise, if 'reg' is not 'NO_REG', set it as the destination -** register. Otherwise, change instruction to a simple 'TEST' (produces -** no register value) -*/ -static int patchtestreg (FuncState *fs, int node, int reg) { - Instruction *i = getjumpcontrol(fs, node); - if (GET_OPCODE(*i) != OP_TESTSET) - return 0; /* cannot patch other instructions */ - if (reg != NO_REG && reg != GETARG_B(*i)) - SETARG_A(*i, reg); - else { - /* no register to put value or register already has the value; - change instruction to simple test */ - *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i)); - } - return 1; -} - - -/* -** Traverse a list of tests ensuring no one produces a value -*/ -static void removevalues (FuncState *fs, int list) { - for (; list != NO_JUMP; list = getjump(fs, list)) - patchtestreg(fs, list, NO_REG); -} - - -/* -** Traverse a list of tests, patching their destination address and -** registers: tests producing values jump to 'vtarget' (and put their -** values in 'reg'), other tests jump to 'dtarget'. -*/ -static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, - int dtarget) { - while (list != NO_JUMP) { - int next = getjump(fs, list); - if (patchtestreg(fs, list, reg)) - fixjump(fs, list, vtarget); - else - fixjump(fs, list, dtarget); /* jump to default target */ - list = next; - } -} - - -/* -** Path all jumps in 'list' to jump to 'target'. -** (The assert means that we cannot fix a jump to a forward address -** because we only know addresses once code is generated.) -*/ -void luaK_patchlist (FuncState *fs, int list, int target) { - lua_assert(target <= fs->pc); - patchlistaux(fs, list, target, NO_REG, target); -} - - -void luaK_patchtohere (FuncState *fs, int list) { - int hr = luaK_getlabel(fs); /* mark "here" as a jump target */ - luaK_patchlist(fs, list, hr); -} - - -/* limit for difference between lines in relative line info. */ -#define LIMLINEDIFF 0x80 - - -/* -** Save line info for a new instruction. If difference from last line -** does not fit in a byte, of after that many instructions, save a new -** absolute line info; (in that case, the special value 'ABSLINEINFO' -** in 'lineinfo' signals the existence of this absolute information.) -** Otherwise, store the difference from last line in 'lineinfo'. -*/ -static void savelineinfo (FuncState *fs, Proto *f, int line) { - int linedif = line - fs->previousline; - int pc = fs->pc - 1; /* last instruction coded */ - if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ >= MAXIWTHABS) { - luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, - f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); - f->abslineinfo[fs->nabslineinfo].pc = pc; - f->abslineinfo[fs->nabslineinfo++].line = line; - linedif = ABSLINEINFO; /* signal that there is absolute information */ - fs->iwthabs = 1; /* restart counter */ - } - luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, - MAX_INT, "opcodes"); - f->lineinfo[pc] = linedif; - fs->previousline = line; /* last line saved */ -} - - -/* -** Remove line information from the last instruction. -** If line information for that instruction is absolute, set 'iwthabs' -** above its max to force the new (replacing) instruction to have -** absolute line info, too. -*/ -static void removelastlineinfo (FuncState *fs) { - Proto *f = fs->f; - int pc = fs->pc - 1; /* last instruction coded */ - if (f->lineinfo[pc] != ABSLINEINFO) { /* relative line info? */ - fs->previousline -= f->lineinfo[pc]; /* correct last line saved */ - fs->iwthabs--; /* undo previous increment */ - } - else { /* absolute line information */ - lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == pc); - fs->nabslineinfo--; /* remove it */ - fs->iwthabs = MAXIWTHABS + 1; /* force next line info to be absolute */ - } -} - - -/* -** Remove the last instruction created, correcting line information -** accordingly. -*/ -static void removelastinstruction (FuncState *fs) { - removelastlineinfo(fs); - fs->pc--; -} - - -/* -** Emit instruction 'i', checking for array sizes and saving also its -** line information. Return 'i' position. -*/ -int luaK_code (FuncState *fs, Instruction i) { - Proto *f = fs->f; - /* put new instruction in code array */ - luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, - MAX_INT, "opcodes"); - f->code[fs->pc++] = i; - savelineinfo(fs, f, fs->ls->lastline); - return fs->pc - 1; /* index of new instruction */ -} - - -/* -** Format and emit an 'iABC' instruction. (Assertions check consistency -** of parameters versus opcode.) -*/ -int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { - lua_assert(getOpMode(o) == iABC); - lua_assert(a <= MAXARG_A && b <= MAXARG_B && - c <= MAXARG_C && (k & ~1) == 0); - return luaK_code(fs, CREATE_ABCk(o, a, b, c, k)); -} - - -/* -** Format and emit an 'iABx' instruction. -*/ -int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { - lua_assert(getOpMode(o) == iABx); - lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); - return luaK_code(fs, CREATE_ABx(o, a, bc)); -} - - -/* -** Format and emit an 'iAsBx' instruction. -*/ -int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) { - unsigned int b = bc + OFFSET_sBx; - lua_assert(getOpMode(o) == iAsBx); - lua_assert(a <= MAXARG_A && b <= MAXARG_Bx); - return luaK_code(fs, CREATE_ABx(o, a, b)); -} - - -/* -** Format and emit an 'isJ' instruction. -*/ -static int codesJ (FuncState *fs, OpCode o, int sj, int k) { - unsigned int j = sj + OFFSET_sJ; - lua_assert(getOpMode(o) == isJ); - lua_assert(j <= MAXARG_sJ && (k & ~1) == 0); - return luaK_code(fs, CREATE_sJ(o, j, k)); -} - - -/* -** Emit an "extra argument" instruction (format 'iAx') -*/ -static int codeextraarg (FuncState *fs, int a) { - lua_assert(a <= MAXARG_Ax); - return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); -} - - -/* -** Emit a "load constant" instruction, using either 'OP_LOADK' -** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX' -** instruction with "extra argument". -*/ -static int luaK_codek (FuncState *fs, int reg, int k) { - if (k <= MAXARG_Bx) - return luaK_codeABx(fs, OP_LOADK, reg, k); - else { - int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); - codeextraarg(fs, k); - return p; - } -} - - -/* -** Check register-stack level, keeping track of its maximum size -** in field 'maxstacksize' -*/ -void luaK_checkstack (FuncState *fs, int n) { - int newstack = fs->freereg + n; - if (newstack > fs->f->maxstacksize) { - if (newstack >= MAXREGS) - luaX_syntaxerror(fs->ls, - "function or expression needs too many registers"); - fs->f->maxstacksize = cast_byte(newstack); - } -} - - -/* -** Reserve 'n' registers in register stack -*/ -void luaK_reserveregs (FuncState *fs, int n) { - luaK_checkstack(fs, n); - fs->freereg += n; -} - - -/* -** Free register 'reg', if it is neither a constant index nor -** a local variable. -) -*/ -static void freereg (FuncState *fs, int reg) { - if (reg >= luaY_nvarstack(fs)) { - fs->freereg--; - lua_assert(reg == fs->freereg); - } -} - - -/* -** Free two registers in proper order -*/ -static void freeregs (FuncState *fs, int r1, int r2) { - if (r1 > r2) { - freereg(fs, r1); - freereg(fs, r2); - } - else { - freereg(fs, r2); - freereg(fs, r1); - } -} - - -/* -** Free register used by expression 'e' (if any) -*/ -static void freeexp (FuncState *fs, expdesc *e) { - if (e->k == VNONRELOC) - freereg(fs, e->u.info); -} - - -/* -** Free registers used by expressions 'e1' and 'e2' (if any) in proper -** order. -*/ -static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { - int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1; - int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1; - freeregs(fs, r1, r2); -} - - -/* -** Add constant 'v' to prototype's list of constants (field 'k'). -** Use scanner's table to cache position of constants in constant list -** and try to reuse constants. Because some values should not be used -** as keys (nil cannot be a key, integer keys can collapse with float -** keys), the caller must provide a useful 'key' for indexing the cache. -** Note that all functions share the same table, so entering or exiting -** a function can make some indices wrong. -*/ -static int addk (FuncState *fs, TValue *key, TValue *v) { - TValue val; - lua_State *L = fs->ls->L; - Proto *f = fs->f; - const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */ - int k, oldsize; - if (ttisinteger(idx)) { /* is there an index there? */ - k = cast_int(ivalue(idx)); - /* correct value? (warning: must distinguish floats from integers!) */ - if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && - luaV_rawequalobj(&f->k[k], v)) - return k; /* reuse index */ - } - /* constant not found; create a new entry */ - 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(&val, k); - luaH_finishset(L, fs->ls->h, key, idx, &val); - 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); - return k; -} - - -/* -** Add a string to list of constants and return its index. -*/ -static int stringK (FuncState *fs, TString *s) { - TValue o; - setsvalue(fs->ls->L, &o, s); - return addk(fs, &o, &o); /* use string itself as key */ -} - - -/* -** Add an integer to list of constants and return its index. -** Integers use userdata as keys to avoid collision with floats with -** same value; conversion to 'void*' is used only for hashing, so there -** are no "precision" problems. -*/ -static int luaK_intK (FuncState *fs, lua_Integer n) { - TValue k, o; - setpvalue(&k, cast_voidp(cast_sizet(n))); - setivalue(&o, n); - return addk(fs, &k, &o); -} - -/* -** Add a float to list of constants and return its index. -*/ -static int luaK_numberK (FuncState *fs, lua_Number r) { - TValue o; - setfltvalue(&o, r); - return addk(fs, &o, &o); /* use number itself as key */ -} - - -/* -** Add a false to list of constants and return its index. -*/ -static int boolF (FuncState *fs) { - TValue o; - setbfvalue(&o); - return addk(fs, &o, &o); /* use boolean itself as key */ -} - - -/* -** Add a true to list of constants and return its index. -*/ -static int boolT (FuncState *fs) { - TValue o; - setbtvalue(&o); - return addk(fs, &o, &o); /* use boolean itself as key */ -} - - -/* -** Add nil to list of constants and return its index. -*/ -static int nilK (FuncState *fs) { - TValue k, v; - setnilvalue(&v); - /* cannot use nil as key; instead use table itself to represent nil */ - sethvalue(fs->ls->L, &k, fs->ls->h); - return addk(fs, &k, &v); -} - - -/* -** Check whether 'i' can be stored in an 'sC' operand. Equivalent to -** (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) but without risk of -** overflows in the hidden addition inside 'int2sC'. -*/ -static int fitsC (lua_Integer i) { - return (l_castS2U(i) + OFFSET_sC <= cast_uint(MAXARG_C)); -} - - -/* -** Check whether 'i' can be stored in an 'sBx' operand. -*/ -static int fitsBx (lua_Integer i) { - return (-OFFSET_sBx <= i && i <= MAXARG_Bx - OFFSET_sBx); -} - - -void luaK_int (FuncState *fs, int reg, lua_Integer i) { - if (fitsBx(i)) - luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i)); - else - luaK_codek(fs, reg, luaK_intK(fs, i)); -} - - -static void luaK_float (FuncState *fs, int reg, lua_Number f) { - lua_Integer fi; - if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) - luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); - else - luaK_codek(fs, reg, luaK_numberK(fs, f)); -} - - -/* -** Convert a constant in 'v' into an expression description 'e' -*/ -static void const2exp (TValue *v, expdesc *e) { - switch (ttypetag(v)) { - case LUA_VNUMINT: - e->k = VKINT; e->u.ival = ivalue(v); - break; - case LUA_VNUMFLT: - e->k = VKFLT; e->u.nval = fltvalue(v); - break; - case LUA_VFALSE: - e->k = VFALSE; - break; - case LUA_VTRUE: - e->k = VTRUE; - break; - case LUA_VNIL: - e->k = VNIL; - break; - case LUA_VSHRSTR: case LUA_VLNGSTR: - e->k = VKSTR; e->u.strval = tsvalue(v); - break; - default: lua_assert(0); - } -} - - -/* -** Fix an expression to return the number of results 'nresults'. -** 'e' must be a multi-ret expression (function call or vararg). -*/ -void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { - Instruction *pc = &getinstruction(fs, e); - if (e->k == VCALL) /* expression is an open function call? */ - SETARG_C(*pc, nresults + 1); - else { - lua_assert(e->k == VVARARG); - SETARG_C(*pc, nresults + 1); - SETARG_A(*pc, fs->freereg); - luaK_reserveregs(fs, 1); - } -} - - -/* -** Convert a VKSTR to a VK -*/ -static void str2K (FuncState *fs, expdesc *e) { - lua_assert(e->k == VKSTR); - e->u.info = stringK(fs, e->u.strval); - e->k = VK; -} - - -/* -** Fix an expression to return one result. -** If expression is not a multi-ret expression (function call or -** vararg), it already returns one result, so nothing needs to be done. -** Function calls become VNONRELOC expressions (as its result comes -** fixed in the base register of the call), while vararg expressions -** become VRELOC (as OP_VARARG puts its results where it wants). -** (Calls are created returning one result, so that does not need -** to be fixed.) -*/ -void luaK_setoneret (FuncState *fs, expdesc *e) { - if (e->k == VCALL) { /* expression is an open function call? */ - /* already returns 1 value */ - lua_assert(GETARG_C(getinstruction(fs, e)) == 2); - e->k = VNONRELOC; /* result has fixed position */ - e->u.info = GETARG_A(getinstruction(fs, e)); - } - else if (e->k == VVARARG) { - SETARG_C(getinstruction(fs, e), 2); - e->k = VRELOC; /* can relocate its simple result */ - } -} - - -/* -** Ensure that expression 'e' is not a variable (nor a ). -** (Expression still may have jump lists.) -*/ -void luaK_dischargevars (FuncState *fs, expdesc *e) { - switch (e->k) { - case VCONST: { - const2exp(const2val(fs, e), e); - break; - } - case VLOCAL: { /* already in a register */ - e->u.info = e->u.var.ridx; - e->k = VNONRELOC; /* becomes a non-relocatable value */ - break; - } - case VUPVAL: { /* move value to some (pending) register */ - e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); - e->k = VRELOC; - break; - } - case VINDEXUP: { - e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx); - e->k = VRELOC; - break; - } - case VINDEXI: { - freereg(fs, e->u.ind.t); - e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx); - e->k = VRELOC; - break; - } - case VINDEXSTR: { - freereg(fs, e->u.ind.t); - e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx); - e->k = VRELOC; - break; - } - case VINDEXED: { - freeregs(fs, e->u.ind.t, e->u.ind.idx); - e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx); - e->k = VRELOC; - break; - } - case VVARARG: case VCALL: { - luaK_setoneret(fs, e); - break; - } - default: break; /* there is one value available (somewhere) */ - } -} - - -/* -** Ensure expression value is in register 'reg', making 'e' a -** non-relocatable expression. -** (Expression still may have jump lists.) -*/ -static void discharge2reg (FuncState *fs, expdesc *e, int reg) { - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: { - luaK_nil(fs, reg, 1); - break; - } - case VFALSE: { - luaK_codeABC(fs, OP_LOADFALSE, reg, 0, 0); - break; - } - case VTRUE: { - luaK_codeABC(fs, OP_LOADTRUE, reg, 0, 0); - break; - } - case VKSTR: { - str2K(fs, e); - } /* FALLTHROUGH */ - case VK: { - luaK_codek(fs, reg, e->u.info); - break; - } - case VKFLT: { - luaK_float(fs, reg, e->u.nval); - break; - } - case VKINT: { - luaK_int(fs, reg, e->u.ival); - break; - } - case VRELOC: { - Instruction *pc = &getinstruction(fs, e); - SETARG_A(*pc, reg); /* instruction will put result in 'reg' */ - break; - } - case VNONRELOC: { - if (reg != e->u.info) - luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); - break; - } - default: { - lua_assert(e->k == VJMP); - return; /* nothing to do... */ - } - } - e->u.info = reg; - e->k = VNONRELOC; -} - - -/* -** Ensure expression value is in a register, making 'e' a -** non-relocatable expression. -** (Expression still may have jump lists.) -*/ -static void discharge2anyreg (FuncState *fs, expdesc *e) { - if (e->k != VNONRELOC) { /* no fixed register yet? */ - luaK_reserveregs(fs, 1); /* get a register */ - discharge2reg(fs, e, fs->freereg-1); /* put value there */ - } -} - - -static int code_loadbool (FuncState *fs, int A, OpCode op) { - luaK_getlabel(fs); /* those instructions may be jump targets */ - return luaK_codeABC(fs, op, A, 0, 0); -} - - -/* -** check whether list has any jump that do not produce a value -** or produce an inverted value -*/ -static int need_value (FuncState *fs, int list) { - for (; list != NO_JUMP; list = getjump(fs, list)) { - Instruction i = *getjumpcontrol(fs, list); - if (GET_OPCODE(i) != OP_TESTSET) return 1; - } - return 0; /* not found */ -} - - -/* -** Ensures final expression result (which includes results from its -** jump lists) is in register 'reg'. -** If expression has jumps, need to patch these jumps either to -** its final position or to "load" instructions (for those tests -** that do not produce values). -*/ -static void exp2reg (FuncState *fs, expdesc *e, int reg) { - discharge2reg(fs, e, reg); - if (e->k == VJMP) /* expression itself is a test? */ - luaK_concat(fs, &e->t, e->u.info); /* put this jump in 't' list */ - if (hasjumps(e)) { - int final; /* position after whole expression */ - int p_f = NO_JUMP; /* position of an eventual LOAD false */ - int p_t = NO_JUMP; /* position of an eventual LOAD true */ - if (need_value(fs, e->t) || need_value(fs, e->f)) { - int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); - p_f = code_loadbool(fs, reg, OP_LFALSESKIP); /* skip next inst. */ - p_t = code_loadbool(fs, reg, OP_LOADTRUE); - /* jump around these booleans if 'e' is not a test */ - luaK_patchtohere(fs, fj); - } - final = luaK_getlabel(fs); - patchlistaux(fs, e->f, final, reg, p_f); - patchlistaux(fs, e->t, final, reg, p_t); - } - e->f = e->t = NO_JUMP; - e->u.info = reg; - e->k = VNONRELOC; -} - - -/* -** Ensures final expression result is in next available register. -*/ -void luaK_exp2nextreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - freeexp(fs, e); - luaK_reserveregs(fs, 1); - exp2reg(fs, e, fs->freereg - 1); -} - - -/* -** Ensures final expression result is in some (any) register -** and return that register. -*/ -int luaK_exp2anyreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - if (e->k == VNONRELOC) { /* expression already has a register? */ - if (!hasjumps(e)) /* no jumps? */ - return e->u.info; /* result is already in a register */ - if (e->u.info >= luaY_nvarstack(fs)) { /* reg. is not a local? */ - exp2reg(fs, e, e->u.info); /* put final result in it */ - return e->u.info; - } - /* else expression has jumps and cannot change its register - to hold the jump values, because it is a local variable. - Go through to the default case. */ - } - luaK_exp2nextreg(fs, e); /* default: use next available register */ - return e->u.info; -} - - -/* -** Ensures final expression result is either in a register -** or in an upvalue. -*/ -void luaK_exp2anyregup (FuncState *fs, expdesc *e) { - if (e->k != VUPVAL || hasjumps(e)) - luaK_exp2anyreg(fs, e); -} - - -/* -** Ensures final expression result is either in a register -** or it is a constant. -*/ -void luaK_exp2val (FuncState *fs, expdesc *e) { - if (hasjumps(e)) - luaK_exp2anyreg(fs, e); - else - luaK_dischargevars(fs, e); -} - - -/* -** Try to make 'e' a K expression with an index in the range of R/K -** indices. Return true iff succeeded. -*/ -static int luaK_exp2K (FuncState *fs, expdesc *e) { - if (!hasjumps(e)) { - int info; - switch (e->k) { /* move constants to 'k' */ - case VTRUE: info = boolT(fs); break; - case VFALSE: info = boolF(fs); break; - case VNIL: info = nilK(fs); break; - case VKINT: info = luaK_intK(fs, e->u.ival); break; - case VKFLT: info = luaK_numberK(fs, e->u.nval); break; - case VKSTR: info = stringK(fs, e->u.strval); break; - case VK: info = e->u.info; break; - default: return 0; /* not a constant */ - } - if (info <= MAXINDEXRK) { /* does constant fit in 'argC'? */ - e->k = VK; /* make expression a 'K' expression */ - e->u.info = info; - return 1; - } - } - /* else, expression doesn't fit; leave it unchanged */ - return 0; -} - - -/* -** Ensures final expression result is in a valid R/K index -** (that is, it is either in a register or in 'k' with an index -** in the range of R/K indices). -** Returns 1 iff expression is K. -*/ -int luaK_exp2RK (FuncState *fs, expdesc *e) { - if (luaK_exp2K(fs, e)) - return 1; - else { /* not a constant in the right range: put it in a register */ - luaK_exp2anyreg(fs, e); - return 0; - } -} - - -static void codeABRK (FuncState *fs, OpCode o, int a, int b, - expdesc *ec) { - int k = luaK_exp2RK(fs, ec); - luaK_codeABCk(fs, o, a, b, ec->u.info, k); -} - - -/* -** Generate code to store result of expression 'ex' into variable 'var'. -*/ -void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { - switch (var->k) { - case VLOCAL: { - freeexp(fs, ex); - exp2reg(fs, ex, var->u.var.ridx); /* compute 'ex' into proper place */ - return; - } - case VUPVAL: { - int e = luaK_exp2anyreg(fs, ex); - luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); - break; - } - case VINDEXUP: { - codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex); - break; - } - case VINDEXI: { - codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex); - break; - } - case VINDEXSTR: { - codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex); - break; - } - case VINDEXED: { - codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex); - break; - } - default: lua_assert(0); /* invalid var kind to store */ - } - freeexp(fs, ex); -} - - -/* -** Emit SELF instruction (convert expression 'e' into 'e:key(e,'). -*/ -void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { - int ereg; - luaK_exp2anyreg(fs, e); - ereg = e->u.info; /* register where 'e' was placed */ - freeexp(fs, e); - e->u.info = fs->freereg; /* base register for op_self */ - e->k = VNONRELOC; /* self expression has a fixed register */ - luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ - codeABRK(fs, OP_SELF, e->u.info, ereg, key); - freeexp(fs, key); -} - - -/* -** Negate condition 'e' (where 'e' is a comparison). -*/ -static void negatecondition (FuncState *fs, expdesc *e) { - Instruction *pc = getjumpcontrol(fs, e->u.info); - lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && - GET_OPCODE(*pc) != OP_TEST); - SETARG_k(*pc, (GETARG_k(*pc) ^ 1)); -} - - -/* -** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond' -** is true, code will jump if 'e' is true.) Return jump position. -** Optimize when 'e' is 'not' something, inverting the condition -** and removing the 'not'. -*/ -static int jumponcond (FuncState *fs, expdesc *e, int cond) { - if (e->k == VRELOC) { - Instruction ie = getinstruction(fs, e); - if (GET_OPCODE(ie) == OP_NOT) { - removelastinstruction(fs); /* remove previous OP_NOT */ - return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond); - } - /* else go through */ - } - discharge2anyreg(fs, e); - freeexp(fs, e); - return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond); -} - - -/* -** Emit code to go through if 'e' is true, jump otherwise. -*/ -void luaK_goiftrue (FuncState *fs, expdesc *e) { - int pc; /* pc of new jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VJMP: { /* condition? */ - negatecondition(fs, e); /* jump when it is false */ - pc = e->u.info; /* save jump position */ - break; - } - case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { - pc = NO_JUMP; /* always true; do nothing */ - break; - } - default: { - pc = jumponcond(fs, e, 0); /* jump when false */ - break; - } - } - luaK_concat(fs, &e->f, pc); /* insert new jump in false list */ - luaK_patchtohere(fs, e->t); /* true list jumps to here (to go through) */ - e->t = NO_JUMP; -} - - -/* -** Emit code to go through if 'e' is false, jump otherwise. -*/ -void luaK_goiffalse (FuncState *fs, expdesc *e) { - int pc; /* pc of new jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VJMP: { - pc = e->u.info; /* already jump if true */ - break; - } - case VNIL: case VFALSE: { - pc = NO_JUMP; /* always false; do nothing */ - break; - } - default: { - pc = jumponcond(fs, e, 1); /* jump if true */ - break; - } - } - luaK_concat(fs, &e->t, pc); /* insert new jump in 't' list */ - luaK_patchtohere(fs, e->f); /* false list jumps to here (to go through) */ - e->f = NO_JUMP; -} - - -/* -** Code 'not e', doing constant folding. -*/ -static void codenot (FuncState *fs, expdesc *e) { - switch (e->k) { - case VNIL: case VFALSE: { - e->k = VTRUE; /* true == not nil == not false */ - break; - } - case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: { - e->k = VFALSE; /* false == not "x" == not 0.5 == not 1 == not true */ - break; - } - case VJMP: { - negatecondition(fs, e); - break; - } - case VRELOC: - case VNONRELOC: { - discharge2anyreg(fs, e); - freeexp(fs, e); - e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); - e->k = VRELOC; - break; - } - default: lua_assert(0); /* cannot happen */ - } - /* interchange true and false lists */ - { int temp = e->f; e->f = e->t; e->t = temp; } - removevalues(fs, e->f); /* values are useless when negated */ - removevalues(fs, e->t); -} - - -/* -** Check whether expression 'e' is a small literal string -*/ -static int isKstr (FuncState *fs, expdesc *e) { - return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B && - ttisshrstring(&fs->f->k[e->u.info])); -} - -/* -** Check whether expression 'e' is a literal integer. -*/ -int luaK_isKint (expdesc *e) { - return (e->k == VKINT && !hasjumps(e)); -} - - -/* -** Check whether expression 'e' is a literal integer in -** proper range to fit in register C -*/ -static int isCint (expdesc *e) { - return luaK_isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); -} - - -/* -** Check whether expression 'e' is a literal integer in -** proper range to fit in register sC -*/ -static int isSCint (expdesc *e) { - return luaK_isKint(e) && fitsC(e->u.ival); -} - - -/* -** Check whether expression 'e' is a literal integer or float in -** proper range to fit in a register (sB or sC). -*/ -static int isSCnumber (expdesc *e, int *pi, int *isfloat) { - lua_Integer i; - if (e->k == VKINT) - i = e->u.ival; - else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq)) - *isfloat = 1; - else - return 0; /* not a number */ - if (!hasjumps(e) && fitsC(i)) { - *pi = int2sC(cast_int(i)); - return 1; - } - else - return 0; -} - - -/* -** Create expression 't[k]'. 't' must have its final result already in a -** register or upvalue. Upvalues can only be indexed by literal strings. -** Keys can be literal strings in the constant table or arbitrary -** values in registers. -*/ -void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { - if (k->k == VKSTR) - str2K(fs, k); - lua_assert(!hasjumps(t) && - (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL)); - if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ - luaK_exp2anyreg(fs, t); /* put it in a register */ - if (t->k == VUPVAL) { - t->u.ind.t = t->u.info; /* upvalue index */ - t->u.ind.idx = k->u.info; /* literal string */ - t->k = VINDEXUP; - } - else { - /* register index of the table */ - t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info; - if (isKstr(fs, k)) { - t->u.ind.idx = k->u.info; /* literal string */ - t->k = VINDEXSTR; - } - else if (isCint(k)) { - t->u.ind.idx = cast_int(k->u.ival); /* int. constant in proper range */ - t->k = VINDEXI; - } - else { - t->u.ind.idx = luaK_exp2anyreg(fs, k); /* register */ - t->k = VINDEXED; - } - } -} - - -/* -** Return false if folding can raise an error. -** Bitwise operations need operands convertible to integers; division -** operations cannot have 0 as divisor. -*/ -static int validop (int op, TValue *v1, TValue *v2) { - switch (op) { - case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: - case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: { /* conversion errors */ - lua_Integer i; - return (luaV_tointegerns(v1, &i, LUA_FLOORN2I) && - luaV_tointegerns(v2, &i, LUA_FLOORN2I)); - } - case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD: /* division by 0 */ - return (nvalue(v2) != 0); - default: return 1; /* everything else is valid */ - } -} - - -/* -** Try to "constant-fold" an operation; return 1 iff successful. -** (In this case, 'e1' has the final result.) -*/ -static int constfolding (FuncState *fs, int op, expdesc *e1, - const expdesc *e2) { - TValue v1, v2, res; - if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) - return 0; /* non-numeric operands or not safe to fold */ - luaO_rawarith(fs->ls->L, op, &v1, &v2, &res); /* does operation */ - if (ttisinteger(&res)) { - e1->k = VKINT; - e1->u.ival = ivalue(&res); - } - else { /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */ - lua_Number n = fltvalue(&res); - if (luai_numisnan(n) || n == 0) - return 0; - e1->k = VKFLT; - e1->u.nval = n; - } - return 1; -} - - -/* -** Emit code for unary expressions that "produce values" -** (everything but 'not'). -** Expression to produce final result will be encoded in 'e'. -*/ -static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { - int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */ - freeexp(fs, e); - e->u.info = luaK_codeABC(fs, op, 0, r, 0); /* generate opcode */ - e->k = VRELOC; /* all those operations are relocatable */ - luaK_fixline(fs, line); -} - - -/* -** Emit code for binary expressions that "produce values" -** (everything but logical operators 'and'/'or' and comparison -** operators). -** Expression to produce final result will be encoded in 'e1'. -*/ -static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, - OpCode op, int v2, int flip, int line, - OpCode mmop, TMS event) { - int v1 = luaK_exp2anyreg(fs, e1); - int pc = luaK_codeABCk(fs, op, 0, v1, v2, 0); - freeexps(fs, e1, e2); - e1->u.info = pc; - e1->k = VRELOC; /* all those operations are relocatable */ - luaK_fixline(fs, line); - luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */ - luaK_fixline(fs, line); -} - - -/* -** Emit code for binary expressions that "produce values" over -** two registers. -*/ -static void codebinexpval (FuncState *fs, OpCode op, - expdesc *e1, expdesc *e2, int line) { - int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ - lua_assert(OP_ADD <= op && op <= OP_SHR); - finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, - cast(TMS, (op - OP_ADD) + TM_ADD)); -} - - -/* -** Code binary operators with immediate operands. -*/ -static void codebini (FuncState *fs, OpCode op, - expdesc *e1, expdesc *e2, int flip, int line, - TMS event) { - int v2 = int2sC(cast_int(e2->u.ival)); /* immediate operand */ - lua_assert(e2->k == VKINT); - finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event); -} - - -/* Try to code a binary operator negating its second operand. -** For the metamethod, 2nd operand must keep its original value. -*/ -static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, - OpCode op, int line, TMS event) { - if (!luaK_isKint(e2)) - return 0; /* not an integer constant */ - else { - lua_Integer i2 = e2->u.ival; - if (!(fitsC(i2) && fitsC(-i2))) - return 0; /* not in the proper range */ - else { /* operating a small integer constant */ - int v2 = cast_int(i2); - finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event); - /* correct metamethod argument */ - SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2)); - return 1; /* successfully coded */ - } - } -} - - -static void swapexps (expdesc *e1, expdesc *e2) { - expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ -} - - -/* -** Code arithmetic operators ('+', '-', ...). If second operand is a -** constant in the proper range, use variant opcodes with K operands. -*/ -static void codearith (FuncState *fs, BinOpr opr, - expdesc *e1, expdesc *e2, int flip, int line) { - TMS event = cast(TMS, opr + TM_ADD); - if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */ - int v2 = e2->u.info; /* K index */ - OpCode op = cast(OpCode, opr + OP_ADDK); - finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); - } - else { /* 'e2' is neither an immediate nor a K operand */ - OpCode op = cast(OpCode, opr + OP_ADD); - if (flip) - swapexps(e1, e2); /* back to original order */ - codebinexpval(fs, op, e1, e2, line); /* use standard operators */ - } -} - - -/* -** Code commutative operators ('+', '*'). If first operand is a -** numeric constant, change order of operands to try to use an -** immediate or K operator. -*/ -static void codecommutative (FuncState *fs, BinOpr op, - expdesc *e1, expdesc *e2, int line) { - int flip = 0; - if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ - swapexps(e1, e2); /* change order */ - flip = 1; - } - if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */ - codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD); - else - codearith(fs, op, e1, e2, flip, line); -} - - -/* -** Code bitwise operations; they are all associative, so the function -** tries to put an integer constant as the 2nd operand (a K operand). -*/ -static void codebitwise (FuncState *fs, BinOpr opr, - expdesc *e1, expdesc *e2, int line) { - int flip = 0; - int v2; - OpCode op; - if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { - swapexps(e1, e2); /* 'e2' will be the constant operand */ - flip = 1; - } - else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ - op = cast(OpCode, opr + OP_ADD); - codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ - return; - } - v2 = e2->u.info; /* index in K array */ - op = cast(OpCode, opr + OP_ADDK); - lua_assert(ttisinteger(&fs->f->k[v2])); - finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, - cast(TMS, opr + TM_ADD)); -} - - -/* -** Emit code for order comparisons. When using an immediate operand, -** 'isfloat' tells whether the original value was a float. -*/ -static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { - int r1, r2; - int im; - int isfloat = 0; - if (isSCnumber(e2, &im, &isfloat)) { - /* use immediate operand */ - r1 = luaK_exp2anyreg(fs, e1); - r2 = im; - op = cast(OpCode, (op - OP_LT) + OP_LTI); - } - else if (isSCnumber(e1, &im, &isfloat)) { - /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ - r1 = luaK_exp2anyreg(fs, e2); - r2 = im; - op = (op == OP_LT) ? OP_GTI : OP_GEI; - } - else { /* regular case, compare two registers */ - r1 = luaK_exp2anyreg(fs, e1); - r2 = luaK_exp2anyreg(fs, e2); - } - freeexps(fs, e1, e2); - e1->u.info = condjump(fs, op, r1, r2, isfloat, 1); - e1->k = VJMP; -} - - -/* -** Emit code for equality comparisons ('==', '~='). -** 'e1' was already put as RK by 'luaK_infix'. -*/ -static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { - int r1, r2; - int im; - int isfloat = 0; /* not needed here, but kept for symmetry */ - OpCode op; - if (e1->k != VNONRELOC) { - lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); - swapexps(e1, e2); - } - r1 = luaK_exp2anyreg(fs, e1); /* 1st expression must be in register */ - if (isSCnumber(e2, &im, &isfloat)) { - op = OP_EQI; - r2 = im; /* immediate operand */ - } - else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */ - op = OP_EQK; - r2 = e2->u.info; /* constant index */ - } - else { - op = OP_EQ; /* will compare two registers */ - r2 = luaK_exp2anyreg(fs, e2); - } - freeexps(fs, e1, e2); - e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ)); - e1->k = VJMP; -} - - -/* -** Apply prefix operation 'op' to expression 'e'. -*/ -void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { - static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; - luaK_dischargevars(fs, e); - switch (op) { - case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ - if (constfolding(fs, op + LUA_OPUNM, e, &ef)) - break; - /* else */ /* FALLTHROUGH */ - case OPR_LEN: - codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line); - break; - case OPR_NOT: codenot(fs, e); break; - default: lua_assert(0); - } -} - - -/* -** Process 1st operand 'v' of binary operation 'op' before reading -** 2nd operand. -*/ -void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { - luaK_dischargevars(fs, v); - switch (op) { - case OPR_AND: { - luaK_goiftrue(fs, v); /* go ahead only if 'v' is true */ - break; - } - case OPR_OR: { - luaK_goiffalse(fs, v); /* go ahead only if 'v' is false */ - break; - } - case OPR_CONCAT: { - luaK_exp2nextreg(fs, v); /* operand must be on the stack */ - break; - } - case OPR_ADD: case OPR_SUB: - case OPR_MUL: case OPR_DIV: case OPR_IDIV: - case OPR_MOD: case OPR_POW: - case OPR_BAND: case OPR_BOR: case OPR_BXOR: - case OPR_SHL: case OPR_SHR: { - if (!tonumeral(v, NULL)) - luaK_exp2anyreg(fs, v); - /* else keep numeral, which may be folded with 2nd operand */ - break; - } - case OPR_EQ: case OPR_NE: { - if (!tonumeral(v, NULL)) - luaK_exp2RK(fs, v); - /* else keep numeral, which may be an immediate operand */ - break; - } - case OPR_LT: case OPR_LE: - case OPR_GT: case OPR_GE: { - int dummy, dummy2; - if (!isSCnumber(v, &dummy, &dummy2)) - luaK_exp2anyreg(fs, v); - /* else keep numeral, which may be an immediate operand */ - break; - } - default: lua_assert(0); - } -} - -/* -** Create code for '(e1 .. e2)'. -** For '(e1 .. e2.1 .. e2.2)' (which is '(e1 .. (e2.1 .. e2.2))', -** because concatenation is right associative), merge both CONCATs. -*/ -static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int line) { - Instruction *ie2 = previousinstruction(fs); - if (GET_OPCODE(*ie2) == OP_CONCAT) { /* is 'e2' a concatenation? */ - int n = GETARG_B(*ie2); /* # of elements concatenated in 'e2' */ - lua_assert(e1->u.info + 1 == GETARG_A(*ie2)); - freeexp(fs, e2); - SETARG_A(*ie2, e1->u.info); /* correct first element ('e1') */ - SETARG_B(*ie2, n + 1); /* will concatenate one more element */ - } - else { /* 'e2' is not a concatenation */ - luaK_codeABC(fs, OP_CONCAT, e1->u.info, 2, 0); /* new concat opcode */ - freeexp(fs, e2); - luaK_fixline(fs, line); - } -} - - -/* -** Finalize code for binary operation, after reading 2nd operand. -*/ -void luaK_posfix (FuncState *fs, BinOpr opr, - expdesc *e1, expdesc *e2, int line) { - luaK_dischargevars(fs, e2); - if (foldbinop(opr) && constfolding(fs, opr + LUA_OPADD, e1, e2)) - return; /* done by folding */ - switch (opr) { - case OPR_AND: { - lua_assert(e1->t == NO_JUMP); /* list closed by 'luaK_infix' */ - luaK_concat(fs, &e2->f, e1->f); - *e1 = *e2; - break; - } - case OPR_OR: { - lua_assert(e1->f == NO_JUMP); /* list closed by 'luaK_infix' */ - luaK_concat(fs, &e2->t, e1->t); - *e1 = *e2; - break; - } - case OPR_CONCAT: { /* e1 .. e2 */ - luaK_exp2nextreg(fs, e2); - codeconcat(fs, e1, e2, line); - break; - } - case OPR_ADD: case OPR_MUL: { - codecommutative(fs, opr, e1, e2, line); - break; - } - case OPR_SUB: { - if (finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB)) - break; /* coded as (r1 + -I) */ - /* ELSE */ - } /* FALLTHROUGH */ - case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { - codearith(fs, opr, e1, e2, 0, line); - break; - } - case OPR_BAND: case OPR_BOR: case OPR_BXOR: { - codebitwise(fs, opr, e1, e2, line); - break; - } - case OPR_SHL: { - if (isSCint(e1)) { - swapexps(e1, e2); - codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); /* I << r2 */ - } - else if (finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL)) { - /* coded as (r1 >> -I) */; - } - else /* regular case (two registers) */ - codebinexpval(fs, OP_SHL, e1, e2, line); - break; - } - case OPR_SHR: { - if (isSCint(e2)) - codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */ - else /* regular case (two registers) */ - codebinexpval(fs, OP_SHR, e1, e2, line); - break; - } - case OPR_EQ: case OPR_NE: { - codeeq(fs, opr, e1, e2); - break; - } - case OPR_LT: case OPR_LE: { - OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ); - codeorder(fs, op, e1, e2); - break; - } - case OPR_GT: case OPR_GE: { - /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */ - OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ); - swapexps(e1, e2); - codeorder(fs, op, e1, e2); - break; - } - default: lua_assert(0); - } -} - - -/* -** Change line information associated with current position, by removing -** previous info and adding it again with new line. -*/ -void luaK_fixline (FuncState *fs, int line) { - removelastlineinfo(fs); - savelineinfo(fs, fs->f, line); -} - - -void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { - Instruction *inst = &fs->f->code[pc]; - int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0; /* hash size */ - int extra = asize / (MAXARG_C + 1); /* higher bits of array size */ - int rc = asize % (MAXARG_C + 1); /* lower bits of array size */ - int k = (extra > 0); /* true iff needs extra argument */ - *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); - *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); -} - - -/* -** Emit a SETLIST instruction. -** 'base' is register that keeps table; -** 'nelems' is #table plus those to be stored now; -** 'tostore' is number of values (in registers 'base + 1',...) to add to -** table (or LUA_MULTRET to add up to stack top). -*/ -void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { - lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); - if (tostore == LUA_MULTRET) - tostore = 0; - if (nelems <= MAXARG_C) - luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems); - else { - int extra = nelems / (MAXARG_C + 1); - nelems %= (MAXARG_C + 1); - luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1); - codeextraarg(fs, extra); - } - fs->freereg = base + 1; /* free registers with list values */ -} - - -/* -** return the final target of a jump (skipping jumps to jumps) -*/ -static int finaltarget (Instruction *code, int i) { - int count; - for (count = 0; count < 100; count++) { /* avoid infinite loops */ - Instruction pc = code[i]; - if (GET_OPCODE(pc) != OP_JMP) - break; - else - i += GETARG_sJ(pc) + 1; - } - return i; -} - - -/* -** Do a final pass over the code of a function, doing small peephole -** optimizations and adjustments. -*/ -void luaK_finish (FuncState *fs) { - int i; - Proto *p = fs->f; - for (i = 0; i < fs->pc; i++) { - Instruction *pc = &p->code[i]; - lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc)); - switch (GET_OPCODE(*pc)) { - case OP_RETURN0: case OP_RETURN1: { - if (!(fs->needclose || p->is_vararg)) - break; /* no extra work */ - /* else use OP_RETURN to do the extra work */ - SET_OPCODE(*pc, OP_RETURN); - } /* FALLTHROUGH */ - case OP_RETURN: case OP_TAILCALL: { - if (fs->needclose) - SETARG_k(*pc, 1); /* signal that it needs to close */ - if (p->is_vararg) - SETARG_C(*pc, p->numparams + 1); /* signal that it is vararg */ - break; - } - case OP_JMP: { - int target = finaltarget(p->code, i); - fixjump(fs, i, target); - break; - } - default: break; - } - } -} diff --git a/source/external/lua/lcode.h b/source/external/lua/lcode.h index 3265824..09e5c80 100644 --- a/source/external/lua/lcode.h +++ b/source/external/lua/lcode.h @@ -60,27 +60,28 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); -LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); -LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx); -LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, - int B, int C, int k); -LUAI_FUNC int luaK_isKint (expdesc *e); +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, int Bx); +LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, int B, int C, + int k); +LUAI_FUNC int luaK_codevABCk (FuncState *fs, OpCode o, int A, int B, int C, + int k); LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); LUAI_FUNC void luaK_fixline (FuncState *fs, int line); LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_codecheckglobal (FuncState *fs, expdesc *var, int k, + int line); LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); +LUAI_FUNC void luaK_vapar2local (FuncState *fs, expdesc *var); LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); -LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); -LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); @@ -98,7 +99,7 @@ LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize); LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); LUAI_FUNC void luaK_finish (FuncState *fs); -LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); +LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *fmt, ...); #endif diff --git a/source/external/lua/lcorolib.c b/source/external/lua/lcorolib.c deleted file mode 100644 index fedbebe..0000000 --- a/source/external/lua/lcorolib.c +++ /dev/null @@ -1,210 +0,0 @@ -/* -** $Id: lcorolib.c $ -** Coroutine Library -** See Copyright Notice in lua.h -*/ - -#define lcorolib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -static lua_State *getco (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - luaL_argexpected(L, co, 1, "thread"); - return co; -} - - -/* -** Resumes a coroutine. Returns the number of results for non-error -** cases or -1 for errors. -*/ -static int auxresume (lua_State *L, lua_State *co, int narg) { - int status, nres; - if (l_unlikely(!lua_checkstack(co, narg))) { - lua_pushliteral(L, "too many arguments to resume"); - return -1; /* error flag */ - } - lua_xmove(L, co, narg); - status = lua_resume(co, L, narg, &nres); - if (l_likely(status == LUA_OK || status == LUA_YIELD)) { - if (l_unlikely(!lua_checkstack(L, nres + 1))) { - lua_pop(co, nres); /* remove results anyway */ - lua_pushliteral(L, "too many results to resume"); - return -1; /* error flag */ - } - lua_xmove(co, L, nres); /* move yielded values */ - return nres; - } - else { - lua_xmove(co, L, 1); /* move error message */ - return -1; /* error flag */ - } -} - - -static int luaB_coresume (lua_State *L) { - lua_State *co = getco(L); - int r; - r = auxresume(L, co, lua_gettop(L) - 1); - if (l_unlikely(r < 0)) { - lua_pushboolean(L, 0); - lua_insert(L, -2); - return 2; /* return false + error message */ - } - else { - lua_pushboolean(L, 1); - lua_insert(L, -(r + 1)); - return r + 1; /* return true + 'resume' returns */ - } -} - - -static int luaB_auxwrap (lua_State *L) { - lua_State *co = lua_tothread(L, lua_upvalueindex(1)); - int r = auxresume(L, co, lua_gettop(L)); - if (l_unlikely(r < 0)) { /* error? */ - int stat = lua_status(co); - if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ - stat = lua_resetthread(co); /* close its tbc variables */ - lua_assert(stat != LUA_OK); - lua_xmove(co, L, 1); /* copy error message */ - } - if (stat != LUA_ERRMEM && /* not a memory error and ... */ - lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ - luaL_where(L, 1); /* add extra info, if available */ - lua_insert(L, -2); - lua_concat(L, 2); - } - return lua_error(L); /* propagate error */ - } - return r; -} - - -static int luaB_cocreate (lua_State *L) { - lua_State *NL; - luaL_checktype(L, 1, LUA_TFUNCTION); - NL = lua_newthread(L); - lua_pushvalue(L, 1); /* move function to top */ - lua_xmove(L, NL, 1); /* move function from L to NL */ - return 1; -} - - -static int luaB_cowrap (lua_State *L) { - luaB_cocreate(L); - lua_pushcclosure(L, luaB_auxwrap, 1); - return 1; -} - - -static int luaB_yield (lua_State *L) { - return lua_yield(L, lua_gettop(L)); -} - - -#define COS_RUN 0 -#define COS_DEAD 1 -#define COS_YIELD 2 -#define COS_NORM 3 - - -static const char *const statname[] = - {"running", "dead", "suspended", "normal"}; - - -static int auxstatus (lua_State *L, lua_State *co) { - if (L == co) return COS_RUN; - else { - switch (lua_status(co)) { - case LUA_YIELD: - return COS_YIELD; - case LUA_OK: { - lua_Debug ar; - if (lua_getstack(co, 0, &ar)) /* does it have frames? */ - return COS_NORM; /* it is running */ - else if (lua_gettop(co) == 0) - return COS_DEAD; - else - return COS_YIELD; /* initial state */ - } - default: /* some error occurred */ - return COS_DEAD; - } - } -} - - -static int luaB_costatus (lua_State *L) { - lua_State *co = getco(L); - lua_pushstring(L, statname[auxstatus(L, co)]); - return 1; -} - - -static int luaB_yieldable (lua_State *L) { - lua_State *co = lua_isnone(L, 1) ? L : getco(L); - lua_pushboolean(L, lua_isyieldable(co)); - return 1; -} - - -static int luaB_corunning (lua_State *L) { - int ismain = lua_pushthread(L); - lua_pushboolean(L, ismain); - return 2; -} - - -static int luaB_close (lua_State *L) { - lua_State *co = getco(L); - int status = auxstatus(L, co); - switch (status) { - case COS_DEAD: case COS_YIELD: { - status = lua_resetthread(co); - if (status == LUA_OK) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushboolean(L, 0); - lua_xmove(co, L, 1); /* copy error message */ - return 2; - } - } - default: /* normal or running coroutine */ - return luaL_error(L, "cannot close a %s coroutine", statname[status]); - } -} - - -static const luaL_Reg co_funcs[] = { - {"create", luaB_cocreate}, - {"resume", luaB_coresume}, - {"running", luaB_corunning}, - {"status", luaB_costatus}, - {"wrap", luaB_cowrap}, - {"yield", luaB_yield}, - {"isyieldable", luaB_yieldable}, - {"close", luaB_close}, - {NULL, NULL} -}; - - - -LUAMOD_API int luaopen_coroutine (lua_State *L) { - luaL_newlib(L, co_funcs); - return 1; -} - diff --git a/source/external/lua/lctype.c b/source/external/lua/lctype.c deleted file mode 100644 index 9542280..0000000 --- a/source/external/lua/lctype.c +++ /dev/null @@ -1,64 +0,0 @@ -/* -** $Id: lctype.c $ -** 'ctype' functions for Lua -** See Copyright Notice in lua.h -*/ - -#define lctype_c -#define LUA_CORE - -#include "lprefix.h" - - -#include "lctype.h" - -#if !LUA_USE_CTYPE /* { */ - -#include - - -#if defined (LUA_UCID) /* accept UniCode IDentifiers? */ -/* consider all non-ascii codepoints to be alphabetic */ -#define NONA 0x01 -#else -#define NONA 0x00 /* default */ -#endif - - -LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { - 0x00, /* EOZ */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ - 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ - 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, - 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ - 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, - 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ - NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, - NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -#endif /* } */ diff --git a/source/external/lua/ldblib.c b/source/external/lua/ldblib.c deleted file mode 100644 index 6dcbaa9..0000000 --- a/source/external/lua/ldblib.c +++ /dev/null @@ -1,483 +0,0 @@ -/* -** $Id: ldblib.c $ -** Interface from Lua to its debug API -** See Copyright Notice in lua.h -*/ - -#define ldblib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* -** The hook table at registry[HOOKKEY] maps threads to their current -** hook function. -*/ -static const char *const HOOKKEY = "_HOOKKEY"; - - -/* -** If L1 != L, L1 can be in any state, and therefore there are no -** guarantees about its stack space; any push in L1 must be -** checked. -*/ -static void checkstack (lua_State *L, lua_State *L1, int n) { - if (l_unlikely(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; -} - - -static int db_getmetatable (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_getmetatable(L, 1)) { - lua_pushnil(L); /* no metatable */ - } - return 1; -} - - -static int db_setmetatable (lua_State *L) { - int t = lua_type(L, 2); - luaL_argexpected(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table"); - lua_settop(L, 2); - lua_setmetatable(L, 1); - return 1; /* return 1st argument */ -} - - -static int db_getuservalue (lua_State *L) { - int n = (int)luaL_optinteger(L, 2, 1); - if (lua_type(L, 1) != LUA_TUSERDATA) - luaL_pushfail(L); - else if (lua_getiuservalue(L, 1, n) != LUA_TNONE) { - lua_pushboolean(L, 1); - return 2; - } - return 1; -} - - -static int db_setuservalue (lua_State *L) { - int n = (int)luaL_optinteger(L, 3, 1); - luaL_checktype(L, 1, LUA_TUSERDATA); - luaL_checkany(L, 2); - lua_settop(L, 2); - if (!lua_setiuservalue(L, 1, n)) - luaL_pushfail(L); - return 1; -} - - -/* -** Auxiliary function used by several library functions: check for -** an optional thread as function's first argument and set 'arg' with -** 1 if this argument is present (so that functions can skip it to -** access their other arguments) -*/ -static lua_State *getthread (lua_State *L, int *arg) { - if (lua_isthread(L, 1)) { - *arg = 1; - return lua_tothread(L, 1); - } - else { - *arg = 0; - return L; /* function will operate over current thread */ - } -} - - -/* -** Variations of 'lua_settable', used by 'db_getinfo' to put results -** from 'lua_getinfo' into result table. Key is always a string; -** value can be a string, an int, or a boolean. -*/ -static void settabss (lua_State *L, const char *k, const char *v) { - lua_pushstring(L, v); - lua_setfield(L, -2, k); -} - -static void settabsi (lua_State *L, const char *k, int v) { - lua_pushinteger(L, v); - lua_setfield(L, -2, k); -} - -static void settabsb (lua_State *L, const char *k, int v) { - lua_pushboolean(L, v); - lua_setfield(L, -2, k); -} - - -/* -** In function 'db_getinfo', the call to 'lua_getinfo' may push -** results on the stack; later it creates the result table to put -** these objects. Function 'treatstackoption' puts the result from -** 'lua_getinfo' on top of the result table so that it can call -** 'lua_setfield'. -*/ -static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { - if (L == L1) - lua_rotate(L, -2, 1); /* exchange object and table */ - else - lua_xmove(L1, L, 1); /* move object to the "main" stack */ - lua_setfield(L, -2, fname); /* put object into table */ -} - - -/* -** 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, "flnSrtu"); - checkstack(L, L1, 3); - luaL_argcheck(L, options[0] != '>', arg + 2, "invalid option '>'"); - 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 */ - lua_xmove(L, L1, 1); - } - else { /* stack level */ - if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) { - luaL_pushfail(L); /* level out of range */ - return 1; - } - } - if (!lua_getinfo(L1, options, &ar)) - return luaL_argerror(L, arg+2, "invalid option"); - lua_newtable(L); /* table to collect results */ - if (strchr(options, 'S')) { - lua_pushlstring(L, ar.source, ar.srclen); - lua_setfield(L, -2, "source"); - settabss(L, "short_src", ar.short_src); - settabsi(L, "linedefined", ar.linedefined); - settabsi(L, "lastlinedefined", ar.lastlinedefined); - settabss(L, "what", ar.what); - } - if (strchr(options, 'l')) - settabsi(L, "currentline", ar.currentline); - if (strchr(options, 'u')) { - settabsi(L, "nups", ar.nups); - settabsi(L, "nparams", ar.nparams); - settabsb(L, "isvararg", ar.isvararg); - } - if (strchr(options, 'n')) { - settabss(L, "name", ar.name); - settabss(L, "namewhat", ar.namewhat); - } - if (strchr(options, 'r')) { - settabsi(L, "ftransfer", ar.ftransfer); - settabsi(L, "ntransfer", ar.ntransfer); - } - if (strchr(options, 't')) - settabsb(L, "istailcall", ar.istailcall); - if (strchr(options, 'L')) - treatstackoption(L, L1, "activelines"); - if (strchr(options, 'f')) - treatstackoption(L, L1, "func"); - return 1; /* return table */ -} - - -static int db_getlocal (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ - if (lua_isfunction(L, arg + 1)) { /* function argument? */ - lua_pushvalue(L, arg + 1); /* push function */ - lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ - return 1; /* return only name (there is no value) */ - } - else { /* stack-level argument */ - lua_Debug ar; - const char *name; - int level = (int)luaL_checkinteger(L, arg + 1); - if (l_unlikely(!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 */ - lua_pushstring(L, name); /* push name */ - lua_rotate(L, -2, 1); /* re-order */ - return 2; - } - else { - luaL_pushfail(L); /* no name (nor value) */ - return 1; - } - } -} - - -static int db_setlocal (lua_State *L) { - int arg; - const char *name; - lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - int level = (int)luaL_checkinteger(L, arg + 1); - int nvar = (int)luaL_checkinteger(L, arg + 2); - if (l_unlikely(!lua_getstack(L1, level, &ar))) /* out of range? */ - 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) - lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */ - lua_pushstring(L, name); - return 1; -} - - -/* -** get (if 'get' is true) or set an upvalue from a closure -*/ -static int auxupvalue (lua_State *L, int get) { - const char *name; - int n = (int)luaL_checkinteger(L, 2); /* upvalue index */ - luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */ - name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); - if (name == NULL) return 0; - lua_pushstring(L, name); - lua_insert(L, -(get+1)); /* no-op if get is false */ - return get + 1; -} - - -static int db_getupvalue (lua_State *L) { - return auxupvalue(L, 1); -} - - -static int db_setupvalue (lua_State *L) { - luaL_checkany(L, 3); - return auxupvalue(L, 0); -} - - -/* -** Check whether a given upvalue from a given closure exists and -** returns its index -*/ -static void *checkupval (lua_State *L, int argf, int argnup, int *pnup) { - void *id; - int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ - luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ - id = lua_upvalueid(L, argf, nup); - if (pnup) { - luaL_argcheck(L, id != NULL, argnup, "invalid upvalue index"); - *pnup = nup; - } - return id; -} - - -static int db_upvalueid (lua_State *L) { - void *id = checkupval(L, 1, 2, NULL); - if (id != NULL) - lua_pushlightuserdata(L, id); - else - luaL_pushfail(L); - return 1; -} - - -static int db_upvaluejoin (lua_State *L) { - int n1, n2; - checkupval(L, 1, 2, &n1); - checkupval(L, 3, 4, &n2); - luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); - luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); - lua_upvaluejoin(L, 1, n1, 3, n2); - return 0; -} - - -/* -** Call hook function registered at hook table for the current -** thread (if there is one) -*/ -static void hookf (lua_State *L, lua_Debug *ar) { - static const char *const hooknames[] = - {"call", "return", "line", "count", "tail call"}; - lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY); - lua_pushthread(L); - if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ - lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ - if (ar->currentline >= 0) - lua_pushinteger(L, ar->currentline); /* push current line */ - else lua_pushnil(L); - lua_assert(lua_getinfo(L, "lS", ar)); - lua_call(L, 2, 0); /* call hook function */ - } -} - - -/* -** Convert a string mask (for 'sethook') into a bit mask -*/ -static int makemask (const char *smask, int count) { - int mask = 0; - if (strchr(smask, 'c')) mask |= LUA_MASKCALL; - if (strchr(smask, 'r')) mask |= LUA_MASKRET; - if (strchr(smask, 'l')) mask |= LUA_MASKLINE; - if (count > 0) mask |= LUA_MASKCOUNT; - return mask; -} - - -/* -** Convert a bit mask (for 'gethook') into a string mask -*/ -static char *unmakemask (int mask, char *smask) { - int i = 0; - if (mask & LUA_MASKCALL) smask[i++] = 'c'; - if (mask & LUA_MASKRET) smask[i++] = 'r'; - if (mask & LUA_MASKLINE) smask[i++] = 'l'; - smask[i] = '\0'; - return smask; -} - - -static int db_sethook (lua_State *L) { - int arg, mask, count; - lua_Hook func; - lua_State *L1 = getthread(L, &arg); - if (lua_isnoneornil(L, arg+1)) { /* no hook? */ - lua_settop(L, arg+1); - func = NULL; mask = 0; count = 0; /* turn off hooks */ - } - else { - const char *smask = luaL_checkstring(L, arg+2); - luaL_checktype(L, arg+1, LUA_TFUNCTION); - count = (int)luaL_optinteger(L, arg + 3, 0); - func = hookf; mask = makemask(smask, count); - } - if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) { - /* table just created; initialize it */ - lua_pushliteral(L, "k"); - lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ - lua_pushvalue(L, -1); - lua_setmetatable(L, -2); /* metatable(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 */ - lua_sethook(L1, func, mask, count); - return 0; -} - - -static int db_gethook (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - char buff[5]; - int mask = lua_gethookmask(L1); - lua_Hook hook = lua_gethook(L1); - if (hook == NULL) { /* no hook? */ - luaL_pushfail(L); - return 1; - } - else if (hook != hookf) /* external hook? */ - lua_pushliteral(L, "external hook"); - else { /* hook table must exist */ - lua_getfield(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 */ - } - lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ - lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */ - return 3; -} - - -static int db_debug (lua_State *L) { - for (;;) { - char buffer[250]; - lua_writestringerror("%s", "lua_debug> "); - if (fgets(buffer, sizeof(buffer), stdin) == NULL || - strcmp(buffer, "cont\n") == 0) - return 0; - if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || - lua_pcall(L, 0, 0, 0)) - lua_writestringerror("%s\n", luaL_tolstring(L, -1, NULL)); - lua_settop(L, 0); /* remove eventual returns */ - } -} - - -static int db_traceback (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - const char *msg = lua_tostring(L, arg + 1); - if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ - lua_pushvalue(L, arg + 1); /* return it untouched */ - else { - int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0); - luaL_traceback(L, L1, msg, level); - } - return 1; -} - - -static int db_setcstacklimit (lua_State *L) { - int limit = (int)luaL_checkinteger(L, 1); - int res = lua_setcstacklimit(L, limit); - lua_pushinteger(L, res); - return 1; -} - - -static const luaL_Reg dblib[] = { - {"debug", db_debug}, - {"getuservalue", db_getuservalue}, - {"gethook", db_gethook}, - {"getinfo", db_getinfo}, - {"getlocal", db_getlocal}, - {"getregistry", db_getregistry}, - {"getmetatable", db_getmetatable}, - {"getupvalue", db_getupvalue}, - {"upvaluejoin", db_upvaluejoin}, - {"upvalueid", db_upvalueid}, - {"setuservalue", db_setuservalue}, - {"sethook", db_sethook}, - {"setlocal", db_setlocal}, - {"setmetatable", db_setmetatable}, - {"setupvalue", db_setupvalue}, - {"traceback", db_traceback}, - {"setcstacklimit", db_setcstacklimit}, - {NULL, NULL} -}; - - -LUAMOD_API int luaopen_debug (lua_State *L) { - luaL_newlib(L, dblib); - return 1; -} - diff --git a/source/external/lua/ldebug.c b/source/external/lua/ldebug.c deleted file mode 100644 index 1feaab2..0000000 --- a/source/external/lua/ldebug.c +++ /dev/null @@ -1,877 +0,0 @@ -/* -** $Id: ldebug.c $ -** Debug Interface -** See Copyright Notice in lua.h -*/ - -#define ldebug_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include -#include - -#include "lua.h" - -#include "lapi.h" -#include "lcode.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lvm.h" - - - -#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL) - - -static const char *funcnamefromcode (lua_State *L, CallInfo *ci, - const char **name); - - -static int currentpc (CallInfo *ci) { - lua_assert(isLua(ci)); - return pcRel(ci->u.l.savedpc, ci_func(ci)->p); -} - - -/* -** Get a "base line" to find the line corresponding to an instruction. -** Base lines are regularly placed at MAXIWTHABS intervals, so usually -** an integer division gets the right place. When the source file has -** large sequences of empty/comment lines, it may need extra entries, -** so the original estimate needs a correction. -** If the original estimate is -1, the initial 'if' ensures that the -** 'while' will run at least once. -** The assertion that the estimate is a lower bound for the correct base -** is valid as long as the debug info has been generated with the same -** value for MAXIWTHABS or smaller. (Previous releases use a little -** smaller value.) -*/ -static int getbaseline (const Proto *f, int pc, int *basepc) { - if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) { - *basepc = -1; /* start from the beginning */ - return f->linedefined; - } - else { - int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */ - /* estimate must be a lower bond of the correct base */ - lua_assert(i < 0 || - (i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc)); - while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc) - i++; /* low estimate; adjust it */ - *basepc = f->abslineinfo[i].pc; - return f->abslineinfo[i].line; - } -} - - -/* -** Get the line corresponding to instruction 'pc' in function 'f'; -** first gets a base line and from there does the increments until -** the desired instruction. -*/ -int luaG_getfuncline (const Proto *f, int pc) { - if (f->lineinfo == NULL) /* no debug information? */ - return -1; - else { - int basepc; - int baseline = getbaseline(f, pc, &basepc); - while (basepc++ < pc) { /* walk until given instruction */ - lua_assert(f->lineinfo[basepc] != ABSLINEINFO); - baseline += f->lineinfo[basepc]; /* correct line */ - } - return baseline; - } -} - - -static int getcurrentline (CallInfo *ci) { - return luaG_getfuncline(ci_func(ci)->p, currentpc(ci)); -} - - -/* -** Set 'trap' for all active Lua frames. -** This function can be called during a signal, under "reasonable" -** assumptions. A new 'ci' is completely linked in the list before it -** becomes part of the "active" list, and we assume that pointers are -** atomic; see comment in next function. -** (A compiler doing interprocedural optimizations could, theoretically, -** reorder memory writes in such a way that the list could be -** temporarily broken while inserting a new element. We simply assume it -** has no good reasons to do that.) -*/ -static void settraps (CallInfo *ci) { - for (; ci != NULL; ci = ci->previous) - if (isLua(ci)) - ci->u.l.trap = 1; -} - - -/* -** This function can be called during a signal, under "reasonable" -** assumptions. -** Fields 'basehookcount' and 'hookcount' (set by 'resethookcount') -** are for debug only, and it is no problem if they get arbitrary -** values (causes at most one wrong hook call). 'hookmask' is an atomic -** value. We assume that pointers are atomic too (e.g., gcc ensures that -** for all platforms where it runs). Moreover, 'hook' is always checked -** before being called (see 'luaD_hook'). -*/ -LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { - if (func == NULL || mask == 0) { /* turn off hooks? */ - mask = 0; - func = NULL; - } - L->hook = func; - L->basehookcount = count; - resethookcount(L); - L->hookmask = cast_byte(mask); - if (mask) - settraps(L->ci); /* to trace inside 'luaV_execute' */ -} - - -LUA_API lua_Hook lua_gethook (lua_State *L) { - return L->hook; -} - - -LUA_API int lua_gethookmask (lua_State *L) { - return L->hookmask; -} - - -LUA_API int lua_gethookcount (lua_State *L) { - return L->basehookcount; -} - - -LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { - int status; - CallInfo *ci; - if (level < 0) return 0; /* invalid (negative) level */ - lua_lock(L); - for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) - level--; - if (level == 0 && ci != &L->base_ci) { /* level found? */ - status = 1; - ar->i_ci = ci; - } - else status = 0; /* no such level */ - lua_unlock(L); - return status; -} - - -static const char *upvalname (const Proto *p, int uv) { - 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) { - if (clLvalue(s2v(ci->func))->p->is_vararg) { - int nextra = ci->u.l.nextraargs; - if (n >= -nextra) { /* 'n' is negative */ - *pos = ci->func - nextra - (n + 1); - return "(vararg)"; /* generic name for any vararg */ - } - } - return NULL; /* no such vararg */ -} - - -const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) { - StkId base = ci->func + 1; - const char *name = NULL; - if (isLua(ci)) { - if (n < 0) /* access to vararg values? */ - return findvararg(ci, n, pos); - else - name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); - } - if (name == NULL) { /* no 'standard' name? */ - StkId limit = (ci == L->ci) ? L->top : ci->next->func; - if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */ - /* generic name for any valid slot */ - name = isLua(ci) ? "(temporary)" : "(C temporary)"; - } - else - return NULL; /* no name */ - } - if (pos) - *pos = base + (n - 1); - return name; -} - - -LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { - const char *name; - lua_lock(L); - if (ar == NULL) { /* information about non-active function? */ - if (!isLfunction(s2v(L->top - 1))) /* not a Lua function? */ - name = NULL; - else /* consider live variables at function start (parameters) */ - name = luaF_getlocalname(clLvalue(s2v(L->top - 1))->p, n, 0); - } - else { /* active function; get information through 'ar' */ - StkId pos = NULL; /* to avoid warnings */ - name = luaG_findlocal(L, ar->i_ci, n, &pos); - if (name) { - setobjs2s(L, L->top, pos); - api_incr_top(L); - } - } - lua_unlock(L); - return name; -} - - -LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { - StkId pos = NULL; /* to avoid warnings */ - const char *name; - lua_lock(L); - name = luaG_findlocal(L, ar->i_ci, n, &pos); - if (name) { - setobjs2s(L, pos, L->top - 1); - L->top--; /* pop value */ - } - lua_unlock(L); - return name; -} - - -static void funcinfo (lua_Debug *ar, Closure *cl) { - if (noLuaClosure(cl)) { - ar->source = "=[C]"; - ar->srclen = LL("=[C]"); - ar->linedefined = -1; - ar->lastlinedefined = -1; - ar->what = "C"; - } - else { - const Proto *p = cl->l.p; - if (p->source) { - ar->source = getstr(p->source); - ar->srclen = tsslen(p->source); - } - else { - ar->source = "=?"; - ar->srclen = LL("=?"); - } - ar->linedefined = p->linedefined; - ar->lastlinedefined = p->lastlinedefined; - ar->what = (ar->linedefined == 0) ? "main" : "Lua"; - } - luaO_chunkid(ar->short_src, ar->source, ar->srclen); -} - - -static int nextline (const Proto *p, int currentline, int pc) { - if (p->lineinfo[pc] != ABSLINEINFO) - return currentline + p->lineinfo[pc]; - else - return luaG_getfuncline(p, pc); -} - - -static void collectvalidlines (lua_State *L, Closure *f) { - if (noLuaClosure(f)) { - setnilvalue(s2v(L->top)); - api_incr_top(L); - } - else { - int i; - TValue v; - const Proto *p = f->l.p; - int currentline = p->linedefined; - Table *t = luaH_new(L); /* new table to store active lines */ - sethvalue2s(L, L->top, t); /* push it on stack */ - api_incr_top(L); - setbtvalue(&v); /* boolean 'true' to be the value of all indices */ - for (i = 0; i < p->sizelineinfo; i++) { /* for all instructions */ - currentline = nextline(p, currentline, i); /* get its line */ - luaH_setint(L, t, currentline, &v); /* table[line] = true */ - } - } -} - - -static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { - if (ci == NULL) /* no 'ci'? */ - return NULL; /* no info */ - else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */ - *name = "__gc"; - return "metamethod"; /* report it as such */ - } - /* calling function is a known Lua function? */ - else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) - return funcnamefromcode(L, ci->previous, name); - else return NULL; /* no way to find a name */ -} - - -static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, - Closure *f, CallInfo *ci) { - int status = 1; - for (; *what; what++) { - switch (*what) { - case 'S': { - funcinfo(ar, f); - break; - } - case 'l': { - ar->currentline = (ci && isLua(ci)) ? getcurrentline(ci) : -1; - break; - } - case 'u': { - ar->nups = (f == NULL) ? 0 : f->c.nupvalues; - if (noLuaClosure(f)) { - ar->isvararg = 1; - ar->nparams = 0; - } - else { - ar->isvararg = f->l.p->is_vararg; - ar->nparams = f->l.p->numparams; - } - break; - } - case 't': { - ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; - break; - } - case 'n': { - ar->namewhat = getfuncname(L, ci, &ar->name); - if (ar->namewhat == NULL) { - ar->namewhat = ""; /* not found */ - ar->name = NULL; - } - break; - } - case 'r': { - if (ci == NULL || !(ci->callstatus & CIST_TRAN)) - ar->ftransfer = ar->ntransfer = 0; - else { - ar->ftransfer = ci->u2.transferinfo.ftransfer; - ar->ntransfer = ci->u2.transferinfo.ntransfer; - } - break; - } - case 'L': - case 'f': /* handled by lua_getinfo */ - break; - default: status = 0; /* invalid option */ - } - } - return status; -} - - -LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { - int status; - Closure *cl; - CallInfo *ci; - TValue *func; - lua_lock(L); - if (*what == '>') { - ci = NULL; - func = s2v(L->top - 1); - api_check(L, ttisfunction(func), "function expected"); - what++; /* skip the '>' */ - L->top--; /* pop function */ - } - else { - ci = ar->i_ci; - func = s2v(ci->func); - lua_assert(ttisfunction(func)); - } - cl = ttisclosure(func) ? clvalue(func) : NULL; - status = auxgetinfo(L, what, ar, cl, ci); - if (strchr(what, 'f')) { - setobj2s(L, L->top, func); - api_incr_top(L); - } - if (strchr(what, 'L')) - collectvalidlines(L, cl); - lua_unlock(L); - return status; -} - - -/* -** {====================================================== -** Symbolic Execution -** ======================================================= -*/ - -static const char *getobjname (const Proto *p, int lastpc, int reg, - const char **name); - - -/* -** Find a "name" for the constant 'c'. -*/ -static void kname (const Proto *p, int c, const char **name) { - TValue *kvalue = &p->k[c]; - *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?"; -} - - -/* -** Find a "name" for the register 'c'. -*/ -static void rname (const Proto *p, int pc, int c, const char **name) { - const char *what = getobjname(p, pc, c, name); /* search for 'c' */ - if (!(what && *what == 'c')) /* did not find a constant name? */ - *name = "?"; -} - - -/* -** Find a "name" for a 'C' value in an RK instruction. -*/ -static void rkname (const Proto *p, int pc, Instruction i, const char **name) { - int c = GETARG_C(i); /* key index */ - if (GETARG_k(i)) /* is 'c' a constant? */ - kname(p, c, name); - else /* 'c' is a register */ - rname(p, pc, c, name); -} - - -static int filterpc (int pc, int jmptarget) { - if (pc < jmptarget) /* is code conditional (inside a jump)? */ - return -1; /* cannot know who sets that register */ - else return pc; /* current position sets that register */ -} - - -/* -** Try to find last instruction before 'lastpc' that modified register 'reg'. -*/ -static int findsetreg (const Proto *p, int lastpc, int reg) { - int pc; - int setreg = -1; /* keep last instruction that changed 'reg' */ - int jmptarget = 0; /* any code before this address is conditional */ - if (testMMMode(GET_OPCODE(p->code[lastpc]))) - lastpc--; /* previous instruction was not actually executed */ - for (pc = 0; pc < lastpc; pc++) { - Instruction i = p->code[pc]; - OpCode op = GET_OPCODE(i); - int a = GETARG_A(i); - int change; /* true if current instruction changed 'reg' */ - switch (op) { - case OP_LOADNIL: { /* set registers from 'a' to 'a+b' */ - int b = GETARG_B(i); - change = (a <= reg && reg <= a + b); - break; - } - case OP_TFORCALL: { /* affect all regs above its base */ - change = (reg >= a + 2); - break; - } - case OP_CALL: - case OP_TAILCALL: { /* affect all registers above base */ - change = (reg >= a); - break; - } - case OP_JMP: { /* doesn't change registers, but changes 'jmptarget' */ - int b = GETARG_sJ(i); - int dest = pc + 1 + b; - /* jump does not skip 'lastpc' and is larger than current one? */ - if (dest <= lastpc && dest > jmptarget) - jmptarget = dest; /* update 'jmptarget' */ - change = 0; - break; - } - default: /* any instruction that sets A */ - change = (testAMode(op) && reg == a); - break; - } - if (change) - setreg = filterpc(pc, jmptarget); - } - return setreg; -} - - -/* -** Check whether table being indexed by instruction 'i' is the -** environment '_ENV' -*/ -static const char *gxf (const Proto *p, int pc, Instruction i, int isup) { - int t = GETARG_B(i); /* table index */ - const char *name; /* name of indexed variable */ - if (isup) /* is an upvalue? */ - name = upvalname(p, t); - else - getobjname(p, pc, t, &name); - return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; -} - - -static const char *getobjname (const Proto *p, int lastpc, int reg, - const char **name) { - int pc; - *name = luaF_getlocalname(p, reg + 1, lastpc); - if (*name) /* is a local? */ - return "local"; - /* else try symbolic execution */ - pc = findsetreg(p, lastpc, reg); - if (pc != -1) { /* could find instruction? */ - Instruction i = p->code[pc]; - OpCode op = GET_OPCODE(i); - switch (op) { - case OP_MOVE: { - int b = GETARG_B(i); /* move from 'b' to 'a' */ - if (b < GETARG_A(i)) - return getobjname(p, pc, b, name); /* get name for 'b' */ - break; - } - case OP_GETTABUP: { - int k = GETARG_C(i); /* key index */ - kname(p, k, name); - return gxf(p, pc, i, 1); - } - case OP_GETTABLE: { - int k = GETARG_C(i); /* key index */ - rname(p, pc, k, name); - return gxf(p, pc, i, 0); - } - case OP_GETI: { - *name = "integer index"; - return "field"; - } - case OP_GETFIELD: { - int k = GETARG_C(i); /* key index */ - kname(p, k, name); - return gxf(p, pc, i, 0); - } - case OP_GETUPVAL: { - *name = upvalname(p, GETARG_B(i)); - return "upvalue"; - } - case OP_LOADK: - case OP_LOADKX: { - int b = (op == OP_LOADK) ? GETARG_Bx(i) - : GETARG_Ax(p->code[pc + 1]); - if (ttisstring(&p->k[b])) { - *name = svalue(&p->k[b]); - return "constant"; - } - break; - } - case OP_SELF: { - rkname(p, pc, i, name); - return "method"; - } - default: break; /* go through to return NULL */ - } - } - return NULL; /* could not find reasonable name */ -} - - -/* -** Try to find a name for a function based on the code that called it. -** (Only works when function was called by a Lua function.) -** Returns what the name is (e.g., "for iterator", "method", -** "metamethod") and sets '*name' to point to the name. -*/ -static const char *funcnamefromcode (lua_State *L, CallInfo *ci, - const char **name) { - TMS tm = (TMS)0; /* (initial value avoids warnings) */ - const Proto *p = ci_func(ci)->p; /* calling function */ - int pc = currentpc(ci); /* calling instruction index */ - Instruction i = p->code[pc]; /* calling instruction */ - if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ - *name = "?"; - return "hook"; - } - switch (GET_OPCODE(i)) { - case OP_CALL: - case OP_TAILCALL: - return getobjname(p, pc, GETARG_A(i), name); /* get function name */ - case OP_TFORCALL: { /* for iterator */ - *name = "for iterator"; - return "for iterator"; - } - /* other instructions can do calls through metamethods */ - case OP_SELF: case OP_GETTABUP: case OP_GETTABLE: - case OP_GETI: case OP_GETFIELD: - tm = TM_INDEX; - break; - case OP_SETTABUP: case OP_SETTABLE: case OP_SETI: case OP_SETFIELD: - tm = TM_NEWINDEX; - break; - case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { - tm = cast(TMS, GETARG_C(i)); - break; - } - case OP_UNM: tm = TM_UNM; break; - case OP_BNOT: tm = TM_BNOT; break; - case OP_LEN: tm = TM_LEN; break; - case OP_CONCAT: tm = TM_CONCAT; break; - case OP_EQ: tm = TM_EQ; break; - /* no cases for OP_EQI and OP_EQK, as they don't call metamethods */ - case OP_LT: case OP_LTI: case OP_GTI: tm = TM_LT; break; - case OP_LE: case OP_LEI: case OP_GEI: tm = TM_LE; break; - case OP_CLOSE: case OP_RETURN: tm = TM_CLOSE; break; - default: - return NULL; /* cannot find a reasonable name */ - } - *name = getstr(G(L)->tmname[tm]) + 2; - return "metamethod"; -} - -/* }====================================================== */ - - - -/* -** Check whether pointer 'o' points to some value in the stack -** frame of the current function. Because 'o' may not point to a -** value in this stack, we cannot compare it with the region -** boundaries (undefined behaviour in ISO C). -*/ -static int isinstack (CallInfo *ci, const TValue *o) { - StkId pos; - for (pos = ci->func + 1; pos < ci->top; pos++) { - if (o == s2v(pos)) - return 1; - } - return 0; /* not found */ -} - - -/* -** Checks whether value 'o' came from an upvalue. (That can only happen -** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on -** upvalues.) -*/ -static const char *getupvalname (CallInfo *ci, const TValue *o, - const char **name) { - LClosure *c = ci_func(ci); - int i; - for (i = 0; i < c->nupvalues; i++) { - if (c->upvals[i]->v == o) { - *name = upvalname(c->p, i); - return "upvalue"; - } - } - return NULL; -} - - -static const char *varinfo (lua_State *L, const TValue *o) { - const char *name = NULL; /* to avoid warnings */ - CallInfo *ci = L->ci; - const char *kind = NULL; - if (isLua(ci)) { - kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ - if (!kind && isinstack(ci, o)) /* no? try a register */ - kind = getobjname(ci_func(ci)->p, currentpc(ci), - cast_int(cast(StkId, o) - (ci->func + 1)), &name); - } - return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : ""; -} - - -l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { - const char *t = luaT_objtypename(L, o); - luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o)); -} - - -l_noret luaG_callerror (lua_State *L, const TValue *o) { - CallInfo *ci = L->ci; - const char *name = NULL; /* to avoid warnings */ - const char *what = (isLua(ci)) ? funcnamefromcode(L, ci, &name) : NULL; - if (what != NULL) { - const char *t = luaT_objtypename(L, o); - luaG_runerror(L, "%s '%s' is not callable (a %s value)", what, name, t); - } - else - luaG_typeerror(L, o, "call"); -} - - -l_noret luaG_forerror (lua_State *L, const TValue *o, const char *what) { - luaG_runerror(L, "bad 'for' %s (number expected, got %s)", - what, luaT_objtypename(L, o)); -} - - -l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) { - if (ttisstring(p1) || cvt2str(p1)) p1 = p2; - luaG_typeerror(L, p1, "concatenate"); -} - - -l_noret luaG_opinterror (lua_State *L, const TValue *p1, - const TValue *p2, const char *msg) { - if (!ttisnumber(p1)) /* first operand is wrong? */ - p2 = p1; /* now second is wrong */ - luaG_typeerror(L, p2, msg); -} - - -/* -** Error when both values are convertible to numbers, but not to integers -*/ -l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) { - lua_Integer temp; - if (!luaV_tointegerns(p1, &temp, LUA_FLOORN2I)) - p2 = p1; - luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2)); -} - - -l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { - const char *t1 = luaT_objtypename(L, p1); - const char *t2 = luaT_objtypename(L, p2); - if (strcmp(t1, t2) == 0) - luaG_runerror(L, "attempt to compare two %s values", t1); - else - luaG_runerror(L, "attempt to compare %s with %s", t1, t2); -} - - -/* 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), tsslen(src)); - else { /* no source available; use "?" instead */ - buff[0] = '?'; buff[1] = '\0'; - } - return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); -} - - -l_noret luaG_errormsg (lua_State *L) { - if (L->errfunc != 0) { /* is there an error handling function? */ - StkId errfunc = restorestack(L, L->errfunc); - lua_assert(ttisfunction(s2v(errfunc))); - setobjs2s(L, L->top, L->top - 1); /* move argument */ - setobjs2s(L, L->top - 1, errfunc); /* push function */ - L->top++; /* assume EXTRA_STACK */ - luaD_callnoyield(L, L->top - 2, 1); /* call it */ - } - luaD_throw(L, LUA_ERRRUN); -} - - -l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { - CallInfo *ci = L->ci; - const char *msg; - va_list argp; - luaC_checkGC(L); /* error message uses memory */ - va_start(argp, fmt); - 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, getcurrentline(ci)); - luaG_errormsg(L); -} - - -/* -** Check whether new instruction 'newpc' is in a different line from -** previous instruction 'oldpc'. More often than not, 'newpc' is only -** one or a few instructions after 'oldpc' (it must be after, see -** caller), so try to avoid calling 'luaG_getfuncline'. If they are -** too far apart, there is a good chance of a ABSLINEINFO in the way, -** so it goes directly to 'luaG_getfuncline'. -*/ -static int changedline (const Proto *p, int oldpc, int newpc) { - if (p->lineinfo == NULL) /* no debug information? */ - return 0; - if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */ - int delta = 0; /* line diference */ - int pc = oldpc; - for (;;) { - int lineinfo = p->lineinfo[++pc]; - if (lineinfo == ABSLINEINFO) - break; /* cannot compute delta; fall through */ - delta += lineinfo; - if (pc == newpc) - return (delta != 0); /* delta computed successfully */ - } - } - /* either instructions are too far apart or there is an absolute line - info in the way; compute line difference explicitly */ - return (luaG_getfuncline(p, oldpc) != luaG_getfuncline(p, newpc)); -} - - -/* -** Traces the execution of a Lua function. Called before the execution -** of each opcode, when debug is on. 'L->oldpc' stores the last -** instruction traced, to detect line changes. When entering a new -** function, 'npci' will be zero and will test as a new line whatever -** the value of 'oldpc'. Some exceptional conditions may return to -** a function without setting 'oldpc'. In that case, 'oldpc' may be -** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc' -** at most causes an extra call to a line hook.) -** This function is not "Protected" when called, so it should correct -** 'L->top' before calling anything that can run the GC. -*/ -int luaG_traceexec (lua_State *L, const Instruction *pc) { - CallInfo *ci = L->ci; - lu_byte mask = L->hookmask; - const Proto *p = ci_func(ci)->p; - int counthook; - if (!(mask & (LUA_MASKLINE | LUA_MASKCOUNT))) { /* no hooks? */ - ci->u.l.trap = 0; /* don't need to stop again */ - return 0; /* turn off 'trap' */ - } - pc++; /* reference is always next instruction */ - ci->u.l.savedpc = pc; /* save 'pc' */ - counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); - if (counthook) - resethookcount(L); /* reset count */ - else if (!(mask & LUA_MASKLINE)) - return 1; /* no line hook and count != 0; nothing to be done now */ - if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ - ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ - return 1; /* do not call hook again (VM yielded, so it did not move) */ - } - if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */ - L->top = ci->top; /* correct top */ - if (counthook) - luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */ - if (mask & LUA_MASKLINE) { - /* 'L->oldpc' may be invalid; use zero in this case */ - int oldpc = (L->oldpc < p->sizecode) ? L->oldpc : 0; - int npci = pcRel(pc, p); - if (npci <= oldpc || /* call hook when jump back (loop), */ - changedline(p, oldpc, npci)) { /* or when enter new line */ - int newline = luaG_getfuncline(p, npci); - luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */ - } - L->oldpc = npci; /* 'pc' of last call to line hook */ - } - if (L->status == LUA_YIELD) { /* did hook yield? */ - if (counthook) - L->hookcount = 1; /* undo decrement to zero */ - ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ - ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ - luaD_throw(L, LUA_YIELD); - } - return 1; /* keep 'trap' on */ -} - diff --git a/source/external/lua/ldebug.h b/source/external/lua/ldebug.h index 974960e..20d0781 100644 --- a/source/external/lua/ldebug.h +++ b/source/external/lua/ldebug.h @@ -15,7 +15,7 @@ /* Active Lua function (given call info) */ -#define ci_func(ci) (clLvalue(s2v((ci)->func))) +#define ci_func(ci) (clLvalue(s2v((ci)->func.p))) #define resethookcount(L) (L->hookcount = L->basehookcount) @@ -53,11 +53,13 @@ LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2); LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2); +LUAI_FUNC l_noret luaG_errnnil (lua_State *L, LClosure *cl, int k); 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 int luaG_traceexec (lua_State *L, const Instruction *pc); +LUAI_FUNC int luaG_tracecall (lua_State *L); #endif diff --git a/source/external/lua/ldo.c b/source/external/lua/ldo.c deleted file mode 100644 index 7135079..0000000 --- a/source/external/lua/ldo.c +++ /dev/null @@ -1,963 +0,0 @@ -/* -** $Id: ldo.c $ -** Stack and Call structure of Lua -** See Copyright Notice in lua.h -*/ - -#define ldo_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include -#include - -#include "lua.h" - -#include "lapi.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lparser.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lundump.h" -#include "lvm.h" -#include "lzio.h" - - - -#define errorstatus(s) ((s) > LUA_YIELD) - - -/* -** {====================================================== -** Error-recovery functions -** ======================================================= -*/ - -/* -** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By -** default, Lua handles errors with exceptions when compiling as -** C++ code, with _longjmp/_setjmp when asked to use them, and with -** longjmp/setjmp otherwise. -*/ -#if !defined(LUAI_THROW) /* { */ - -#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */ - -/* C++ exceptions */ -#define LUAI_THROW(L,c) throw(c) -#define LUAI_TRY(L,c,a) \ - try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } -#define luai_jmpbuf int /* dummy variable */ - -#elif defined(LUA_USE_POSIX) /* }{ */ - -/* in POSIX, try _longjmp/_setjmp (more efficient) */ -#define LUAI_THROW(L,c) _longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf - -#else /* }{ */ - -/* ISO C handling with long jumps */ -#define LUAI_THROW(L,c) longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf - -#endif /* } */ - -#endif /* } */ - - - -/* chain list of long jump buffers */ -struct lua_longjmp { - struct lua_longjmp *previous; - luai_jmpbuf b; - volatile int status; /* error code */ -}; - - -void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { - switch (errcode) { - case LUA_ERRMEM: { /* memory error? */ - setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ - break; - } - case LUA_ERRERR: { - setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); - break; - } - case LUA_OK: { /* special case only for closing upvalues */ - setnilvalue(s2v(oldtop)); /* no error message */ - break; - } - default: { - lua_assert(errorstatus(errcode)); /* real error */ - setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ - break; - } - } - L->top = oldtop + 1; -} - - -l_noret luaD_throw (lua_State *L, int errcode) { - if (L->errorJmp) { /* thread has an error handler? */ - L->errorJmp->status = errcode; /* set status */ - LUAI_THROW(L, L->errorJmp); /* jump to it */ - } - else { /* thread has no error handler */ - global_State *g = G(L); - errcode = luaE_resetthread(L, errcode); /* close all upvalues */ - if (g->mainthread->errorJmp) { /* main thread has a handler? */ - setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ - luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ - } - else { /* no handler at all; abort */ - if (g->panic) { /* panic function? */ - lua_unlock(L); - g->panic(L); /* call panic function (last chance to jump out) */ - } - abort(); - } - } -} - - -int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { - l_uint32 oldnCcalls = L->nCcalls; - struct lua_longjmp lj; - lj.status = LUA_OK; - lj.previous = L->errorJmp; /* chain new error handler */ - L->errorJmp = &lj; - LUAI_TRY(L, &lj, - (*f)(L, ud); - ); - L->errorJmp = lj.previous; /* restore old error handler */ - L->nCcalls = oldnCcalls; - return lj.status; -} - -/* }====================================================== */ - - -/* -** {================================================================== -** Stack reallocation -** =================================================================== -*/ -static void correctstack (lua_State *L, StkId oldstack, StkId newstack) { - CallInfo *ci; - UpVal *up; - L->top = (L->top - oldstack) + newstack; - L->tbclist = (L->tbclist - oldstack) + newstack; - for (up = L->openupval; up != NULL; up = up->u.open.next) - up->v = s2v((uplevel(up) - oldstack) + newstack); - for (ci = L->ci; ci != NULL; ci = ci->previous) { - ci->top = (ci->top - oldstack) + newstack; - ci->func = (ci->func - oldstack) + newstack; - if (isLua(ci)) - ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */ - } -} - - -/* some space for error handling */ -#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) - - -/* -** Reallocate the stack to a new size, correcting all pointers into -** it. (There are pointers to a stack from its upvalues, from its list -** of call infos, plus a few individual pointers.) The reallocation is -** done in two steps (allocation + free) because the correction must be -** done while both addresses (the old stack and the new one) are valid. -** (In ISO C, any pointer use after the pointer has been deallocated is -** undefined behavior.) -** In case of allocation error, raise an error or return false according -** to 'raiseerror'. -*/ -int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { - int oldsize = stacksize(L); - int i; - StkId newstack = luaM_reallocvector(L, NULL, 0, - newsize + EXTRA_STACK, StackValue); - lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); - if (l_unlikely(newstack == NULL)) { /* reallocation failed? */ - if (raiseerror) - luaM_error(L); - else return 0; /* do not raise an error */ - } - /* number of elements to be copied to the new stack */ - i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK; - memcpy(newstack, L->stack, i * sizeof(StackValue)); - for (; i < newsize + EXTRA_STACK; i++) - setnilvalue(s2v(newstack + i)); /* erase new segment */ - correctstack(L, L->stack, newstack); - luaM_freearray(L, L->stack, oldsize + EXTRA_STACK); - L->stack = newstack; - L->stack_last = L->stack + newsize; - return 1; -} - - -/* -** Try to grow the stack by at least 'n' elements. when 'raiseerror' -** is true, raises any error; otherwise, return 0 in case of errors. -*/ -int luaD_growstack (lua_State *L, int n, int raiseerror) { - int size = stacksize(L); - if (l_unlikely(size > LUAI_MAXSTACK)) { - /* if stack is larger than maximum, thread is already using the - extra space reserved for errors, that is, thread is handling - a stack error; cannot grow further than that. */ - lua_assert(stacksize(L) == ERRORSTACKSIZE); - if (raiseerror) - luaD_throw(L, LUA_ERRERR); /* error inside message handler */ - return 0; /* if not 'raiseerror', just signal it */ - } - else { - int newsize = 2 * size; /* tentative new size */ - int needed = cast_int(L->top - L->stack) + n; - if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ - newsize = LUAI_MAXSTACK; - if (newsize < needed) /* but must respect what was asked for */ - newsize = needed; - if (l_likely(newsize <= LUAI_MAXSTACK)) - return luaD_reallocstack(L, newsize, raiseerror); - else { /* stack overflow */ - /* add extra size to be able to handle the error message */ - luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror); - if (raiseerror) - luaG_runerror(L, "stack overflow"); - return 0; - } - } -} - - -static int stackinuse (lua_State *L) { - CallInfo *ci; - int res; - StkId lim = L->top; - for (ci = L->ci; ci != NULL; ci = ci->previous) { - if (lim < ci->top) lim = ci->top; - } - lua_assert(lim <= L->stack_last); - res = cast_int(lim - L->stack) + 1; /* part of stack in use */ - if (res < LUA_MINSTACK) - res = LUA_MINSTACK; /* ensure a minimum size */ - return res; -} - - -/* -** If stack size is more than 3 times the current use, reduce that size -** to twice the current use. (So, the final stack size is at most 2/3 the -** previous size, and half of its entries are empty.) -** As a particular case, if stack was handling a stack overflow and now -** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than -** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack -** will be reduced to a "regular" size. -*/ -void luaD_shrinkstack (lua_State *L) { - int inuse = stackinuse(L); - int nsize = inuse * 2; /* proposed new size */ - int max = inuse * 3; /* maximum "reasonable" size */ - if (max > LUAI_MAXSTACK) { - max = LUAI_MAXSTACK; /* respect stack limit */ - if (nsize > LUAI_MAXSTACK) - nsize = LUAI_MAXSTACK; - } - /* if thread is currently not handling a stack overflow and its - size is larger than maximum "reasonable" size, shrink it */ - if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) - luaD_reallocstack(L, nsize, 0); /* ok if that fails */ - else /* don't change stack */ - condmovestack(L,{},{}); /* (change only for debugging) */ - luaE_shrinkCI(L); /* shrink CI list */ -} - - -void luaD_inctop (lua_State *L) { - luaD_checkstack(L, 1); - L->top++; -} - -/* }================================================================== */ - - -/* -** Call a hook for the given event. Make sure there is a hook to be -** called. (Both 'L->hook' and 'L->hookmask', which trigger this -** function, can be changed asynchronously by signals.) -*/ -void luaD_hook (lua_State *L, int event, int line, - int ftransfer, int ntransfer) { - lua_Hook hook = L->hook; - if (hook && L->allowhook) { /* make sure there is a hook */ - int mask = CIST_HOOKED; - CallInfo *ci = L->ci; - ptrdiff_t top = savestack(L, L->top); /* preserve original 'top' */ - ptrdiff_t ci_top = savestack(L, ci->top); /* idem for 'ci->top' */ - lua_Debug ar; - ar.event = event; - ar.currentline = line; - ar.i_ci = ci; - if (ntransfer != 0) { - mask |= CIST_TRAN; /* 'ci' has transfer information */ - ci->u2.transferinfo.ftransfer = ftransfer; - ci->u2.transferinfo.ntransfer = ntransfer; - } - if (isLua(ci) && L->top < ci->top) - L->top = ci->top; /* protect entire activation register */ - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - if (ci->top < L->top + LUA_MINSTACK) - ci->top = L->top + LUA_MINSTACK; - L->allowhook = 0; /* cannot call hooks inside a hook */ - ci->callstatus |= mask; - lua_unlock(L); - (*hook)(L, &ar); - lua_lock(L); - lua_assert(!L->allowhook); - L->allowhook = 1; - ci->top = restorestack(L, ci_top); - L->top = restorestack(L, top); - ci->callstatus &= ~mask; - } -} - - -/* -** Executes a call hook for Lua functions. This function is called -** whenever 'hookmask' is not zero, so it checks whether call hooks are -** active. -*/ -void luaD_hookcall (lua_State *L, CallInfo *ci) { - L->oldpc = 0; /* set 'oldpc' for new function */ - if (L->hookmask & LUA_MASKCALL) { /* is call hook on? */ - int event = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL - : LUA_HOOKCALL; - Proto *p = ci_func(ci)->p; - ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ - luaD_hook(L, event, -1, 1, p->numparams); - ci->u.l.savedpc--; /* correct 'pc' */ - } -} - - -/* -** Executes a return hook for Lua and C functions and sets/corrects -** 'oldpc'. (Note that this correction is needed by the line hook, so it -** is done even when return hooks are off.) -*/ -static void rethook (lua_State *L, CallInfo *ci, int nres) { - if (L->hookmask & LUA_MASKRET) { /* is return hook on? */ - StkId firstres = L->top - nres; /* index of first result */ - int delta = 0; /* correction for vararg functions */ - int ftransfer; - if (isLua(ci)) { - Proto *p = ci_func(ci)->p; - if (p->is_vararg) - delta = ci->u.l.nextraargs + p->numparams + 1; - } - ci->func += delta; /* if vararg, back to virtual 'func' */ - ftransfer = cast(unsigned short, firstres - ci->func); - luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ - ci->func -= delta; - } - if (isLua(ci = ci->previous)) - L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */ -} - - -/* -** Check whether 'func' has a '__call' metafield. If so, put it in the -** stack, below original 'func', so that 'luaD_precall' can call it. Raise -** an error if there is no '__call' metafield. -*/ -void luaD_tryfuncTM (lua_State *L, StkId func) { - const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); - StkId p; - if (l_unlikely(ttisnil(tm))) - luaG_callerror(L, s2v(func)); /* nothing to call */ - for (p = L->top; p > func; p--) /* open space for metamethod */ - setobjs2s(L, p, p-1); - L->top++; /* stack space pre-allocated by the caller */ - setobj2s(L, func, tm); /* metamethod is the new function to be called */ -} - - -/* -** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. -** Handle most typical cases (zero results for commands, one result for -** expressions, multiple results for tail calls/single parameters) -** separated. -*/ -static void moveresults (lua_State *L, StkId res, int nres, int wanted) { - StkId firstresult; - int i; - switch (wanted) { /* handle typical cases separately */ - case 0: /* no values needed */ - L->top = res; - return; - case 1: /* one value needed */ - if (nres == 0) /* no results? */ - setnilvalue(s2v(res)); /* adjust with nil */ - else /* at least one result */ - setobjs2s(L, res, L->top - nres); /* move it to proper place */ - L->top = res + 1; - return; - case LUA_MULTRET: - wanted = nres; /* we want all results */ - break; - default: /* two/more results and/or to-be-closed variables */ - if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ - ptrdiff_t savedres = savestack(L, res); - L->ci->callstatus |= CIST_CLSRET; /* in case of yields */ - L->ci->u2.nres = nres; - luaF_close(L, res, CLOSEKTOP, 1); - L->ci->callstatus &= ~CIST_CLSRET; - if (L->hookmask) /* if needed, call hook after '__close's */ - rethook(L, L->ci, nres); - res = restorestack(L, savedres); /* close and hook can move stack */ - wanted = decodeNresults(wanted); - if (wanted == LUA_MULTRET) - wanted = nres; /* we want all results */ - } - break; - } - /* generic case */ - firstresult = L->top - nres; /* index of first result */ - if (nres > wanted) /* extra results? */ - nres = wanted; /* don't need them */ - for (i = 0; i < nres; i++) /* move all results to correct place */ - setobjs2s(L, res + i, firstresult + i); - for (; i < wanted; i++) /* complete wanted number of results */ - setnilvalue(s2v(res + i)); - L->top = res + wanted; /* top points after the last result */ -} - - -/* -** Finishes a function call: calls hook if necessary, moves current -** number of results to proper place, and returns to previous call -** info. If function has to close variables, hook must be called after -** that. -*/ -void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { - int wanted = ci->nresults; - if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted))) - rethook(L, ci, nres); - /* move results to proper place */ - moveresults(L, ci->func, nres, wanted); - /* function cannot be in any of these cases when returning */ - lua_assert(!(ci->callstatus & - (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET))); - L->ci = ci->previous; /* back to caller (after closing variables) */ -} - - - -#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) - - -/* -** Prepare a function for a tail call, building its call info on top -** of the current call info. 'narg1' is the number of arguments plus 1 -** (so that it includes the function itself). -*/ -void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { - Proto *p = clLvalue(s2v(func))->p; - int fsize = p->maxstacksize; /* frame size */ - int nfixparams = p->numparams; - int i; - for (i = 0; i < narg1; i++) /* move down function and arguments */ - setobjs2s(L, ci->func + i, func + i); - checkstackGC(L, fsize); - func = ci->func; /* moved-down function */ - for (; narg1 <= nfixparams; narg1++) - setnilvalue(s2v(func + narg1)); /* complete missing arguments */ - ci->top = func + 1 + fsize; /* top for new function */ - lua_assert(ci->top <= L->stack_last); - ci->u.l.savedpc = p->code; /* starting point */ - ci->callstatus |= CIST_TAIL; - L->top = func + narg1; /* set top */ -} - - -/* -** Prepares the call to a function (C or Lua). For C functions, also do -** the call. The function to be called is at '*func'. The arguments -** are on the stack, right after the function. Returns the CallInfo -** to be executed, if it was a Lua function. Otherwise (a C function) -** returns NULL, with all the results on the stack, starting at the -** original function position. -*/ -CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { - lua_CFunction f; - retry: - switch (ttypetag(s2v(func))) { - case LUA_VCCL: /* C closure */ - f = clCvalue(s2v(func))->f; - goto Cfunc; - case LUA_VLCF: /* light C function */ - f = fvalue(s2v(func)); - Cfunc: { - int n; /* number of returns */ - CallInfo *ci; - checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ - L->ci = ci = next_ci(L); - ci->nresults = nresults; - ci->callstatus = CIST_C; - ci->top = L->top + LUA_MINSTACK; - ci->func = func; - lua_assert(ci->top <= L->stack_last); - if (l_unlikely(L->hookmask & LUA_MASKCALL)) { - int narg = cast_int(L->top - func) - 1; - luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); - } - lua_unlock(L); - n = (*f)(L); /* do the actual call */ - lua_lock(L); - api_checknelems(L, n); - luaD_poscall(L, ci, n); - return NULL; - } - case LUA_VLCL: { /* Lua function */ - CallInfo *ci; - Proto *p = clLvalue(s2v(func))->p; - int narg = cast_int(L->top - func) - 1; /* number of real arguments */ - int nfixparams = p->numparams; - int fsize = p->maxstacksize; /* frame size */ - checkstackGCp(L, fsize, func); - L->ci = ci = next_ci(L); - ci->nresults = nresults; - ci->u.l.savedpc = p->code; /* starting point */ - ci->top = func + 1 + fsize; - ci->func = func; - L->ci = ci; - for (; narg < nfixparams; narg++) - setnilvalue(s2v(L->top++)); /* complete missing arguments */ - lua_assert(ci->top <= L->stack_last); - return ci; - } - default: { /* not a function */ - checkstackGCp(L, 1, func); /* space for metamethod */ - luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ - goto retry; /* try again with metamethod */ - } - } -} - - -/* -** Call a function (C or Lua) through C. 'inc' can be 1 (increment -** number of recursive invocations in the C stack) or nyci (the same -** plus increment number of non-yieldable calls). -*/ -static void ccall (lua_State *L, StkId func, int nResults, int inc) { - CallInfo *ci; - L->nCcalls += inc; - if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) - luaE_checkcstack(L); - if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ - ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ - luaV_execute(L, ci); /* call it */ - } - L->nCcalls -= inc; -} - - -/* -** External interface for 'ccall' -*/ -void luaD_call (lua_State *L, StkId func, int nResults) { - ccall(L, func, nResults, 1); -} - - -/* -** Similar to 'luaD_call', but does not allow yields during the call. -*/ -void luaD_callnoyield (lua_State *L, StkId func, int nResults) { - ccall(L, func, nResults, nyci); -} - - -/* -** Finish the job of 'lua_pcallk' after it was interrupted by an yield. -** (The caller, 'finishCcall', does the final call to 'adjustresults'.) -** The main job is to complete the 'luaD_pcall' called by 'lua_pcallk'. -** If a '__close' method yields here, eventually control will be back -** to 'finishCcall' (when that '__close' method finally returns) and -** 'finishpcallk' will run again and close any still pending '__close' -** methods. Similarly, if a '__close' method errs, 'precover' calls -** 'unroll' which calls ''finishCcall' and we are back here again, to -** close any pending '__close' methods. -** Note that, up to the call to 'luaF_close', the corresponding -** 'CallInfo' is not modified, so that this repeated run works like the -** first one (except that it has at least one less '__close' to do). In -** particular, field CIST_RECST preserves the error status across these -** multiple runs, changing only if there is a new error. -*/ -static int finishpcallk (lua_State *L, CallInfo *ci) { - int status = getcistrecst(ci); /* get original status */ - if (l_likely(status == LUA_OK)) /* no error? */ - status = LUA_YIELD; /* was interrupted by an yield */ - else { /* error */ - StkId func = restorestack(L, ci->u2.funcidx); - L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */ - luaF_close(L, func, status, 1); /* can yield or raise an error */ - func = restorestack(L, ci->u2.funcidx); /* stack may be moved */ - luaD_seterrorobj(L, status, func); - luaD_shrinkstack(L); /* restore stack size in case of overflow */ - setcistrecst(ci, LUA_OK); /* clear original status */ - } - ci->callstatus &= ~CIST_YPCALL; - L->errfunc = ci->u.c.old_errfunc; - /* if it is here, there were errors or yields; unlike 'lua_pcallk', - do not change status */ - return status; -} - - -/* -** Completes the execution of a C function interrupted by an yield. -** The interruption must have happened while the function was either -** closing its tbc variables in 'moveresults' or executing -** 'lua_callk'/'lua_pcallk'. In the first case, it just redoes -** 'luaD_poscall'. In the second case, the call to 'finishpcallk' -** finishes the interrupted execution of 'lua_pcallk'. After that, it -** calls the continuation of the interrupted function and finally it -** completes the job of the 'luaD_call' that called the function. In -** the call to 'adjustresults', we do not know the number of results -** of the function called by 'lua_callk'/'lua_pcallk', so we are -** conservative and use LUA_MULTRET (always adjust). -*/ -static void finishCcall (lua_State *L, CallInfo *ci) { - int n; /* actual number of results from C function */ - if (ci->callstatus & CIST_CLSRET) { /* was returning? */ - lua_assert(hastocloseCfunc(ci->nresults)); - n = ci->u2.nres; /* just redo 'luaD_poscall' */ - /* don't need to reset CIST_CLSRET, as it will be set again anyway */ - } - else { - int status = LUA_YIELD; /* default if there were no errors */ - /* must have a continuation and must be able to call it */ - lua_assert(ci->u.c.k != NULL && yieldable(L)); - if (ci->callstatus & CIST_YPCALL) /* was inside a 'lua_pcallk'? */ - status = finishpcallk(L, ci); /* finish it */ - adjustresults(L, LUA_MULTRET); /* finish 'lua_callk' */ - lua_unlock(L); - n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation */ - lua_lock(L); - api_checknelems(L, n); - } - luaD_poscall(L, ci, n); /* finish 'luaD_call' */ -} - - -/* -** Executes "full continuation" (everything in the stack) of a -** previously interrupted coroutine until the stack is empty (or another -** interruption long-jumps out of the loop). -*/ -static void unroll (lua_State *L, void *ud) { - CallInfo *ci; - UNUSED(ud); - while ((ci = L->ci) != &L->base_ci) { /* something in the stack */ - if (!isLua(ci)) /* C function? */ - finishCcall(L, ci); /* complete its execution */ - else { /* Lua function */ - luaV_finishOp(L); /* finish interrupted instruction */ - luaV_execute(L, ci); /* execute down to higher C 'boundary' */ - } - } -} - - -/* -** Try to find a suspended protected call (a "recover point") for the -** given thread. -*/ -static CallInfo *findpcall (lua_State *L) { - CallInfo *ci; - for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ - if (ci->callstatus & CIST_YPCALL) - return ci; - } - return NULL; /* no pending pcall */ -} - - -/* -** Signal an error in the call to 'lua_resume', not in the execution -** of the coroutine itself. (Such errors should not be handled by any -** coroutine error handler and should not kill the coroutine.) -*/ -static int resume_error (lua_State *L, const char *msg, int narg) { - L->top -= narg; /* remove args from the stack */ - setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ - api_incr_top(L); - lua_unlock(L); - return LUA_ERRRUN; -} - - -/* -** Do the work for 'lua_resume' in protected mode. Most of the work -** depends on the status of the coroutine: initial state, suspended -** inside a hook, or regularly suspended (optionally with a continuation -** function), plus erroneous cases: non-suspended coroutine or dead -** coroutine. -*/ -static void resume (lua_State *L, void *ud) { - int n = *(cast(int*, ud)); /* number of arguments */ - StkId firstArg = L->top - n; /* first argument */ - CallInfo *ci = L->ci; - if (L->status == LUA_OK) /* starting a coroutine? */ - ccall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ - else { /* resuming from previous yield */ - lua_assert(L->status == LUA_YIELD); - L->status = LUA_OK; /* mark that it is running (again) */ - luaE_incCstack(L); /* control the C stack */ - if (isLua(ci)) { /* yielded inside a hook? */ - L->top = firstArg; /* discard arguments */ - luaV_execute(L, ci); /* just continue running Lua code */ - } - else { /* 'common' yield */ - if (ci->u.c.k != NULL) { /* does it have a continuation function? */ - lua_unlock(L); - n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */ - lua_lock(L); - api_checknelems(L, n); - } - luaD_poscall(L, ci, n); /* finish 'luaD_call' */ - } - unroll(L, NULL); /* run continuation */ - } -} - - -/* -** Unrolls a coroutine in protected mode while there are recoverable -** errors, that is, errors inside a protected call. (Any error -** interrupts 'unroll', and this loop protects it again so it can -** continue.) Stops with a normal end (status == LUA_OK), an yield -** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't -** find a recover point). -*/ -static int precover (lua_State *L, int status) { - CallInfo *ci; - while (errorstatus(status) && (ci = findpcall(L)) != NULL) { - L->ci = ci; /* go down to recovery functions */ - setcistrecst(ci, status); /* status to finish 'pcall' */ - status = luaD_rawrunprotected(L, unroll, NULL); - } - return status; -} - - -LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, - int *nresults) { - int status; - lua_lock(L); - if (L->status == LUA_OK) { /* may be starting a coroutine */ - if (L->ci != &L->base_ci) /* not in base level? */ - return resume_error(L, "cannot resume non-suspended coroutine", nargs); - else if (L->top - (L->ci->func + 1) == nargs) /* no function? */ - return resume_error(L, "cannot resume dead coroutine", nargs); - } - else if (L->status != LUA_YIELD) /* ended with errors? */ - return resume_error(L, "cannot resume dead coroutine", nargs); - L->nCcalls = (from) ? getCcalls(from) : 0; - luai_userstateresume(L, nargs); - api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); - status = luaD_rawrunprotected(L, resume, &nargs); - /* continue running after recoverable errors */ - status = precover(L, status); - if (l_likely(!errorstatus(status))) - lua_assert(status == L->status); /* normal end or yield */ - else { /* unrecoverable error */ - L->status = cast_byte(status); /* mark thread as 'dead' */ - luaD_seterrorobj(L, status, L->top); /* push error message */ - L->ci->top = L->top; - } - *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield - : cast_int(L->top - (L->ci->func + 1)); - lua_unlock(L); - return status; -} - - -LUA_API int lua_isyieldable (lua_State *L) { - return yieldable(L); -} - - -LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, - lua_KFunction k) { - CallInfo *ci; - luai_userstateyield(L, nresults); - lua_lock(L); - ci = L->ci; - api_checknelems(L, nresults); - if (l_unlikely(!yieldable(L))) { - if (L != G(L)->mainthread) - luaG_runerror(L, "attempt to yield across a C-call boundary"); - else - luaG_runerror(L, "attempt to yield from outside a coroutine"); - } - L->status = LUA_YIELD; - ci->u2.nyield = nresults; /* save number of results */ - if (isLua(ci)) { /* inside a hook? */ - lua_assert(!isLuacode(ci)); - api_check(L, nresults == 0, "hooks cannot yield values"); - api_check(L, k == NULL, "hooks cannot continue after yielding"); - } - else { - if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ - ci->u.c.ctx = ctx; /* save context */ - luaD_throw(L, LUA_YIELD); - } - lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ - lua_unlock(L); - return 0; /* return to 'luaD_hook' */ -} - - -/* -** Auxiliary structure to call 'luaF_close' in protected mode. -*/ -struct CloseP { - StkId level; - int status; -}; - - -/* -** Auxiliary function to call 'luaF_close' in protected mode. -*/ -static void closepaux (lua_State *L, void *ud) { - struct CloseP *pcl = cast(struct CloseP *, ud); - luaF_close(L, pcl->level, pcl->status, 0); -} - - -/* -** Calls 'luaF_close' in protected mode. Return the original status -** or, in case of errors, the new status. -*/ -int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) { - CallInfo *old_ci = L->ci; - lu_byte old_allowhooks = L->allowhook; - for (;;) { /* keep closing upvalues until no more errors */ - struct CloseP pcl; - pcl.level = restorestack(L, level); pcl.status = status; - status = luaD_rawrunprotected(L, &closepaux, &pcl); - if (l_likely(status == LUA_OK)) /* no more errors? */ - return pcl.status; - else { /* an error occurred; restore saved state and repeat */ - L->ci = old_ci; - L->allowhook = old_allowhooks; - } - } -} - - -/* -** Call the C function 'func' in protected mode, restoring basic -** thread information ('allowhook', etc.) and in particular -** its stack level in case of errors. -*/ -int luaD_pcall (lua_State *L, Pfunc func, void *u, - ptrdiff_t old_top, ptrdiff_t ef) { - int status; - CallInfo *old_ci = L->ci; - lu_byte old_allowhooks = L->allowhook; - ptrdiff_t old_errfunc = L->errfunc; - L->errfunc = ef; - status = luaD_rawrunprotected(L, func, u); - if (l_unlikely(status != LUA_OK)) { /* an error occurred? */ - L->ci = old_ci; - L->allowhook = old_allowhooks; - status = luaD_closeprotected(L, old_top, status); - luaD_seterrorobj(L, status, restorestack(L, old_top)); - luaD_shrinkstack(L); /* restore stack size in case of overflow */ - } - L->errfunc = old_errfunc; - return status; -} - - - -/* -** Execute a protected parser. -*/ -struct SParser { /* data to 'f_parser' */ - ZIO *z; - Mbuffer buff; /* dynamic structure used by the scanner */ - Dyndata dyd; /* dynamic structures used by the parser */ - const char *mode; - const char *name; -}; - - -static void checkmode (lua_State *L, const char *mode, const char *x) { - if (mode && strchr(mode, x[0]) == NULL) { - luaO_pushfstring(L, - "attempt to load a %s chunk (mode is '%s')", x, mode); - luaD_throw(L, LUA_ERRSYNTAX); - } -} - - -static void f_parser (lua_State *L, void *ud) { - LClosure *cl; - struct SParser *p = cast(struct SParser *, ud); - int c = zgetc(p->z); /* read first character */ - if (c == LUA_SIGNATURE[0]) { - checkmode(L, p->mode, "binary"); - cl = luaU_undump(L, p->z, p->name); - } - else { - checkmode(L, p->mode, "text"); - cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); - } - lua_assert(cl->nupvalues == cl->p->sizeupvalues); - luaF_initupvals(L, cl); -} - - -int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, - const char *mode) { - struct SParser p; - int status; - incnny(L); /* cannot yield during parsing */ - p.z = z; p.name = name; p.mode = mode; - p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; - p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; - p.dyd.label.arr = NULL; p.dyd.label.size = 0; - luaZ_initbuffer(L, &p.buff); - status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); - luaZ_freebuffer(L, &p.buff); - luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); - luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); - luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); - decnny(L); - return status; -} - - diff --git a/source/external/lua/ldo.h b/source/external/lua/ldo.h index 6bf0ed8..b647295 100644 --- a/source/external/lua/ldo.h +++ b/source/external/lua/ldo.h @@ -8,6 +8,7 @@ #define ldo_h +#include "llimits.h" #include "lobject.h" #include "lstate.h" #include "lzio.h" @@ -22,58 +23,77 @@ ** 'condmovestack' is used in heavy tests to force a stack reallocation ** at every check. */ + +#if !defined(HARDSTACKTESTS) +#define condmovestack(L,pre,pos) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L,pre,pos) \ + { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } +#endif + #define luaD_checkstackaux(L,n,pre,pos) \ - if (l_unlikely(L->stack_last - L->top <= (n))) \ + if (l_unlikely(L->stack_last.p - L->top.p <= (n))) \ { pre; luaD_growstack(L, n, 1); pos; } \ - else { condmovestack(L,pre,pos); } + else { condmovestack(L,pre,pos); } /* In general, 'pre'/'pos' are empty (nothing to save) */ #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) -#define savestack(L,p) ((char *)(p) - (char *)L->stack) -#define restorestack(L,n) ((StkId)((char *)L->stack + (n))) +#define savestack(L,pt) (cast_charp(pt) - cast_charp(L->stack.p)) +#define restorestack(L,n) cast(StkId, cast_charp(L->stack.p) + (n)) /* macro to check stack size, preserving 'p' */ -#define checkstackGCp(L,n,p) \ +#define checkstackp(L,n,p) \ luaD_checkstackaux(L, n, \ - ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ - luaC_checkGC(L), /* stack grow uses memory */ \ + ptrdiff_t t__ = savestack(L, p), /* save 'p' */ \ p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ -/* macro to check stack size and GC */ -#define checkstackGC(L,fsize) \ - luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) +/* +** Maximum depth for nested C calls, syntactical nested non-terminals, +** and other features implemented through recursion in C. (Value must +** fit in a 16-bit unsigned integer. It must also be compatible with +** the size of the C stack.) +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 200 +#endif /* type of protected functions, to be ran by 'runprotected' */ typedef void (*Pfunc) (lua_State *L, void *ud); -LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); -LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, +LUAI_FUNC l_noret luaD_errerr (lua_State *L); +LUAI_FUNC void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop); +LUAI_FUNC TStatus luaD_protectedparser (lua_State *L, ZIO *z, + const char *name, const char *mode); LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, int fTransfer, int nTransfer); LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); -LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); +LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, + int narg1, int delta); LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); -LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); -LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); -LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, +LUAI_FUNC TStatus luaD_closeprotected (lua_State *L, ptrdiff_t level, + TStatus status); +LUAI_FUNC TStatus luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t oldtop, ptrdiff_t ef); LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); LUAI_FUNC void luaD_shrinkstack (lua_State *L); LUAI_FUNC void luaD_inctop (lua_State *L); +LUAI_FUNC int luaD_checkminstack (lua_State *L); -LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); -LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); +LUAI_FUNC l_noret luaD_throw (lua_State *L, TStatus errcode); +LUAI_FUNC l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode); +LUAI_FUNC TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); #endif diff --git a/source/external/lua/ldump.c b/source/external/lua/ldump.c deleted file mode 100644 index f848b66..0000000 --- a/source/external/lua/ldump.c +++ /dev/null @@ -1,226 +0,0 @@ -/* -** $Id: ldump.c $ -** save precompiled Lua chunks -** See Copyright Notice in lua.h -*/ - -#define ldump_c -#define LUA_CORE - -#include "lprefix.h" - - -#include - -#include "lua.h" - -#include "lobject.h" -#include "lstate.h" -#include "lundump.h" - - -typedef struct { - lua_State *L; - lua_Writer writer; - void *data; - int strip; - int status; -} DumpState; - - -/* -** All high-level dumps go through dumpVector; you can change it to -** change the endianness of the result -*/ -#define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) - -#define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) - - -static void dumpBlock (DumpState *D, const void *b, size_t size) { - if (D->status == 0 && size > 0) { - lua_unlock(D->L); - D->status = (*D->writer)(D->L, b, size, D->data); - lua_lock(D->L); - } -} - - -#define dumpVar(D,x) dumpVector(D,&x,1) - - -static void dumpByte (DumpState *D, int y) { - lu_byte x = (lu_byte)y; - dumpVar(D, x); -} - - -/* dumpInt Buff Size */ -#define DIBS ((sizeof(size_t) * 8 / 7) + 1) - -static void dumpSize (DumpState *D, size_t x) { - lu_byte buff[DIBS]; - int n = 0; - do { - buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ - x >>= 7; - } while (x != 0); - buff[DIBS - 1] |= 0x80; /* mark last byte */ - dumpVector(D, buff + DIBS - n, n); -} - - -static void dumpInt (DumpState *D, int x) { - dumpSize(D, x); -} - - -static void dumpNumber (DumpState *D, lua_Number x) { - dumpVar(D, x); -} - - -static void dumpInteger (DumpState *D, lua_Integer x) { - dumpVar(D, x); -} - - -static void dumpString (DumpState *D, const TString *s) { - if (s == NULL) - dumpSize(D, 0); - else { - size_t size = tsslen(s); - const char *str = getstr(s); - dumpSize(D, size + 1); - dumpVector(D, str, size); - } -} - - -static void dumpCode (DumpState *D, const Proto *f) { - dumpInt(D, f->sizecode); - dumpVector(D, f->code, f->sizecode); -} - - -static void dumpFunction(DumpState *D, const Proto *f, TString *psource); - -static void dumpConstants (DumpState *D, const Proto *f) { - int i; - int n = f->sizek; - dumpInt(D, n); - for (i = 0; i < n; i++) { - const TValue *o = &f->k[i]; - int tt = ttypetag(o); - dumpByte(D, tt); - switch (tt) { - case LUA_VNUMFLT: - dumpNumber(D, fltvalue(o)); - break; - case LUA_VNUMINT: - dumpInteger(D, ivalue(o)); - break; - case LUA_VSHRSTR: - case LUA_VLNGSTR: - dumpString(D, tsvalue(o)); - break; - default: - lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); - } - } -} - - -static void dumpProtos (DumpState *D, const Proto *f) { - int i; - int n = f->sizep; - dumpInt(D, n); - for (i = 0; i < n; i++) - dumpFunction(D, f->p[i], f->source); -} - - -static void dumpUpvalues (DumpState *D, const Proto *f) { - int i, n = f->sizeupvalues; - dumpInt(D, n); - for (i = 0; i < n; i++) { - dumpByte(D, f->upvalues[i].instack); - dumpByte(D, f->upvalues[i].idx); - dumpByte(D, f->upvalues[i].kind); - } -} - - -static void dumpDebug (DumpState *D, const Proto *f) { - int i, n; - n = (D->strip) ? 0 : f->sizelineinfo; - dumpInt(D, n); - dumpVector(D, f->lineinfo, n); - n = (D->strip) ? 0 : f->sizeabslineinfo; - dumpInt(D, n); - for (i = 0; i < n; i++) { - dumpInt(D, f->abslineinfo[i].pc); - dumpInt(D, f->abslineinfo[i].line); - } - n = (D->strip) ? 0 : f->sizelocvars; - dumpInt(D, n); - for (i = 0; i < n; i++) { - dumpString(D, f->locvars[i].varname); - dumpInt(D, f->locvars[i].startpc); - dumpInt(D, f->locvars[i].endpc); - } - n = (D->strip) ? 0 : f->sizeupvalues; - dumpInt(D, n); - for (i = 0; i < n; i++) - dumpString(D, f->upvalues[i].name); -} - - -static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { - if (D->strip || f->source == psource) - dumpString(D, NULL); /* no debug info or same source as its parent */ - else - dumpString(D, f->source); - dumpInt(D, f->linedefined); - dumpInt(D, f->lastlinedefined); - dumpByte(D, f->numparams); - dumpByte(D, f->is_vararg); - dumpByte(D, f->maxstacksize); - dumpCode(D, f); - dumpConstants(D, f); - dumpUpvalues(D, f); - dumpProtos(D, f); - dumpDebug(D, f); -} - - -static void dumpHeader (DumpState *D) { - dumpLiteral(D, LUA_SIGNATURE); - dumpByte(D, LUAC_VERSION); - dumpByte(D, LUAC_FORMAT); - dumpLiteral(D, LUAC_DATA); - dumpByte(D, sizeof(Instruction)); - dumpByte(D, sizeof(lua_Integer)); - dumpByte(D, sizeof(lua_Number)); - dumpInteger(D, LUAC_INT); - dumpNumber(D, LUAC_NUM); -} - - -/* -** dump Lua function as precompiled chunk -*/ -int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, - int strip) { - DumpState D; - D.L = L; - D.writer = w; - D.data = data; - D.strip = strip; - D.status = 0; - dumpHeader(&D); - dumpByte(&D, f->sizeupvalues); - dumpFunction(&D, f, NULL); - return D.status; -} - diff --git a/source/external/lua/lfunc.c b/source/external/lua/lfunc.c deleted file mode 100644 index f5889a2..0000000 --- a/source/external/lua/lfunc.c +++ /dev/null @@ -1,294 +0,0 @@ -/* -** $Id: lfunc.c $ -** Auxiliary functions to manipulate prototypes and closures -** See Copyright Notice in lua.h -*/ - -#define lfunc_c -#define LUA_CORE - -#include "lprefix.h" - - -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" - - - -CClosure *luaF_newCclosure (lua_State *L, int nupvals) { - GCObject *o = luaC_newobj(L, LUA_VCCL, sizeCclosure(nupvals)); - CClosure *c = gco2ccl(o); - c->nupvalues = cast_byte(nupvals); - return c; -} - - -LClosure *luaF_newLclosure (lua_State *L, int nupvals) { - GCObject *o = luaC_newobj(L, LUA_VLCL, sizeLclosure(nupvals)); - LClosure *c = gco2lcl(o); - c->p = NULL; - c->nupvalues = cast_byte(nupvals); - while (nupvals--) c->upvals[nupvals] = NULL; - return c; -} - - -/* -** fill a closure with new closed upvalues -*/ -void luaF_initupvals (lua_State *L, LClosure *cl) { - int i; - for (i = 0; i < cl->nupvalues; i++) { - GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); - UpVal *uv = gco2upv(o); - uv->v = &uv->u.value; /* make it closed */ - setnilvalue(uv->v); - cl->upvals[i] = uv; - luaC_objbarrier(L, cl, uv); - } -} - - -/* -** Create a new upvalue at the given level, and link it to the list of -** open upvalues of 'L' after entry 'prev'. -**/ -static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) { - GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal)); - UpVal *uv = gco2upv(o); - UpVal *next = *prev; - uv->v = s2v(level); /* current value lives in the stack */ - uv->tbc = tbc; - uv->u.open.next = next; /* link it to list of open upvalues */ - uv->u.open.previous = prev; - if (next) - next->u.open.previous = &uv->u.open.next; - *prev = uv; - if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ - L->twups = G(L)->twups; /* link it to the list */ - G(L)->twups = L; - } - return uv; -} - - -/* -** Find and reuse, or create if it does not exist, an upvalue -** at the given level. -*/ -UpVal *luaF_findupval (lua_State *L, StkId level) { - UpVal **pp = &L->openupval; - UpVal *p; - lua_assert(isintwups(L) || L->openupval == NULL); - while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ - lua_assert(!isdead(G(L), p)); - if (uplevel(p) == level) /* corresponding upvalue? */ - return p; /* return it */ - pp = &p->u.open.next; - } - /* not found: create a new upvalue after 'pp' */ - return newupval(L, 0, level, pp); -} - - -/* -** Call closing method for object 'obj' with error message 'err'. The -** boolean 'yy' controls whether the call is yieldable. -** (This function assumes EXTRA_STACK.) -*/ -static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) { - StkId top = L->top; - const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); - setobj2s(L, top, tm); /* will call metamethod... */ - setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */ - setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */ - L->top = top + 3; /* add function and arguments */ - if (yy) - luaD_call(L, top, 0); - else - luaD_callnoyield(L, top, 0); -} - - -/* -** Check whether object at given level has a close metamethod and raise -** an error if not. -*/ -static void checkclosemth (lua_State *L, StkId level) { - const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE); - if (ttisnil(tm)) { /* no metamethod? */ - int idx = cast_int(level - L->ci->func); /* variable index */ - const char *vname = luaG_findlocal(L, L->ci, idx, NULL); - if (vname == NULL) vname = "?"; - luaG_runerror(L, "variable '%s' got a non-closable value", vname); - } -} - - -/* -** Prepare and call a closing method. -** If status is CLOSEKTOP, the call to the closing method will be pushed -** at the top of the stack. Otherwise, values can be pushed right after -** the 'level' of the upvalue being closed, as everything after that -** won't be used again. -*/ -static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) { - TValue *uv = s2v(level); /* value being closed */ - TValue *errobj; - if (status == CLOSEKTOP) - errobj = &G(L)->nilvalue; /* error object is nil */ - else { /* 'luaD_seterrorobj' will set top to level + 2 */ - errobj = s2v(level + 1); /* error object goes after 'uv' */ - luaD_seterrorobj(L, status, level + 1); /* set error object */ - } - callclosemethod(L, uv, errobj, yy); -} - - -/* -** Maximum value for deltas in 'tbclist', dependent on the type -** of delta. (This macro assumes that an 'L' is in scope where it -** is used.) -*/ -#define MAXDELTA \ - ((256ul << ((sizeof(L->stack->tbclist.delta) - 1) * 8)) - 1) - - -/* -** Insert a variable in the list of to-be-closed variables. -*/ -void luaF_newtbcupval (lua_State *L, StkId level) { - lua_assert(level > L->tbclist); - if (l_isfalse(s2v(level))) - return; /* false doesn't need to be closed */ - checkclosemth(L, level); /* value must have a close method */ - while (cast_uint(level - L->tbclist) > MAXDELTA) { - L->tbclist += MAXDELTA; /* create a dummy node at maximum delta */ - L->tbclist->tbclist.delta = 0; - } - level->tbclist.delta = cast(unsigned short, level - L->tbclist); - L->tbclist = level; -} - - -void luaF_unlinkupval (UpVal *uv) { - lua_assert(upisopen(uv)); - *uv->u.open.previous = uv->u.open.next; - if (uv->u.open.next) - uv->u.open.next->u.open.previous = uv->u.open.previous; -} - - -/* -** Close all upvalues up to the given stack level. -*/ -void luaF_closeupval (lua_State *L, StkId level) { - UpVal *uv; - StkId upl; /* stack index pointed by 'uv' */ - while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) { - TValue *slot = &uv->u.value; /* new position for value */ - lua_assert(uplevel(uv) < L->top); - luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */ - setobj(L, slot, uv->v); /* move value to upvalue slot */ - uv->v = slot; /* now current value lives here */ - if (!iswhite(uv)) { /* neither white nor dead? */ - nw2black(uv); /* closed upvalues cannot be gray */ - luaC_barrier(L, uv, slot); - } - } -} - - -/* -** Remove firt element from the tbclist plus its dummy nodes. -*/ -static void poptbclist (lua_State *L) { - StkId tbc = L->tbclist; - lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */ - tbc -= tbc->tbclist.delta; - while (tbc > L->stack && tbc->tbclist.delta == 0) - tbc -= MAXDELTA; /* remove dummy nodes */ - L->tbclist = tbc; -} - - -/* -** Close all upvalues and to-be-closed variables up to the given stack -** level. -*/ -void luaF_close (lua_State *L, StkId level, int status, int yy) { - ptrdiff_t levelrel = savestack(L, level); - luaF_closeupval(L, level); /* first, close the upvalues */ - while (L->tbclist >= level) { /* traverse tbc's down to that level */ - StkId tbc = L->tbclist; /* get variable index */ - poptbclist(L); /* remove it from list */ - prepcallclosemth(L, tbc, status, yy); /* close variable */ - level = restorestack(L, levelrel); - } -} - - -Proto *luaF_newproto (lua_State *L) { - GCObject *o = luaC_newobj(L, LUA_VPROTO, sizeof(Proto)); - Proto *f = gco2p(o); - f->k = NULL; - f->sizek = 0; - f->p = NULL; - f->sizep = 0; - f->code = NULL; - f->sizecode = 0; - f->lineinfo = NULL; - f->sizelineinfo = 0; - f->abslineinfo = NULL; - f->sizeabslineinfo = 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; -} - - -void luaF_freeproto (lua_State *L, Proto *f) { - 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->abslineinfo, f->sizeabslineinfo); - luaM_freearray(L, f->locvars, f->sizelocvars); - luaM_freearray(L, f->upvalues, f->sizeupvalues); - luaM_free(L, f); -} - - -/* -** Look for n-th local variable at line 'line' in function 'func'. -** Returns NULL if not found. -*/ -const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { - int i; - for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { - if (pc < f->locvars[i].endpc) { /* is variable active? */ - local_number--; - if (local_number == 0) - return getstr(f->locvars[i].varname); - } - } - return NULL; /* not found */ -} - diff --git a/source/external/lua/lfunc.h b/source/external/lua/lfunc.h index dc1cebc..d6aad3a 100644 --- a/source/external/lua/lfunc.h +++ b/source/external/lua/lfunc.h @@ -11,11 +11,11 @@ #include "lobject.h" -#define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ - cast_int(sizeof(TValue)) * (n)) +#define sizeCclosure(n) \ + (offsetof(CClosure, upvalue) + sizeof(TValue) * cast_uint(n)) -#define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ - cast_int(sizeof(TValue *)) * (n)) +#define sizeLclosure(n) \ + (offsetof(LClosure, upvals) + sizeof(UpVal *) * cast_uint(n)) /* test whether thread is in 'twups' list */ @@ -29,10 +29,10 @@ #define MAXUPVAL 255 -#define upisopen(up) ((up)->v != &(up)->u.value) +#define upisopen(up) ((up)->v.p != &(up)->u.value) -#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) +#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p)) /* @@ -44,7 +44,7 @@ /* special status to close upvalues preserving the top of the stack */ -#define CLOSEKTOP (-1) +#define CLOSEKTOP (LUA_ERRERR + 1) LUAI_FUNC Proto *luaF_newproto (lua_State *L); @@ -54,8 +54,9 @@ LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); -LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); +LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, TStatus status, int yy); LUAI_FUNC void luaF_unlinkupval (UpVal *uv); +LUAI_FUNC lu_mem luaF_protosize (Proto *p); LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, int pc); diff --git a/source/external/lua/lgc.c b/source/external/lua/lgc.c deleted file mode 100644 index b360eed..0000000 --- a/source/external/lua/lgc.c +++ /dev/null @@ -1,1728 +0,0 @@ -/* -** $Id: lgc.c $ -** Garbage Collector -** See Copyright Notice in lua.h -*/ - -#define lgc_c -#define LUA_CORE - -#include "lprefix.h" - -#include -#include - - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" - - -/* -** Maximum number of elements to sweep in each single step. -** (Large enough to dissipate fixed overheads but small enough -** to allow small steps for the collector.) -*/ -#define GCSWEEPMAX 100 - -/* -** Maximum number of finalizers to call in each single step. -*/ -#define GCFINMAX 10 - - -/* -** Cost of calling one finalizer. -*/ -#define GCFINALIZECOST 50 - - -/* -** The equivalent, in bytes, of one unit of "work" (visiting a slot, -** sweeping an object, etc.) -*/ -#define WORK2MEM sizeof(TValue) - - -/* -** macro to adjust 'pause': 'pause' is actually used like -** 'pause / PAUSEADJ' (value chosen by tests) -*/ -#define PAUSEADJ 100 - - -/* mask with all color bits */ -#define maskcolors (bitmask(BLACKBIT) | WHITEBITS) - -/* mask with all GC bits */ -#define maskgcbits (maskcolors | AGEBITS) - - -/* macro to erase all color bits then set only the current white bit */ -#define makewhite(g,x) \ - (x->marked = cast_byte((x->marked & ~maskcolors) | luaC_white(g))) - -/* make an object gray (neither white nor black) */ -#define set2gray(x) resetbits(x->marked, maskcolors) - - -/* make an object black (coming from any color) */ -#define set2black(x) \ - (x->marked = cast_byte((x->marked & ~WHITEBITS) | bitmask(BLACKBIT))) - - -#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) - -#define keyiswhite(n) (keyiscollectable(n) && iswhite(gckey(n))) - - -/* -** Protected access to objects in values -*/ -#define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) - - -#define markvalue(g,o) { checkliveness(g->mainthread,o); \ - if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } - -#define markkey(g, n) { if keyiswhite(n) reallymarkobject(g,gckey(n)); } - -#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); -static lu_mem atomic (lua_State *L); -static void entersweep (lua_State *L); - - -/* -** {====================================================== -** Generic functions -** ======================================================= -*/ - - -/* -** one after last element in a hash array -*/ -#define gnodelast(h) gnode(h, cast_sizet(sizenode(h))) - - -static GCObject **getgclist (GCObject *o) { - switch (o->tt) { - case LUA_VTABLE: return &gco2t(o)->gclist; - case LUA_VLCL: return &gco2lcl(o)->gclist; - case LUA_VCCL: return &gco2ccl(o)->gclist; - case LUA_VTHREAD: return &gco2th(o)->gclist; - case LUA_VPROTO: return &gco2p(o)->gclist; - case LUA_VUSERDATA: { - Udata *u = gco2u(o); - lua_assert(u->nuvalue > 0); - return &u->gclist; - } - default: lua_assert(0); return 0; - } -} - - -/* -** Link a collectable object 'o' with a known type into the list 'p'. -** (Must be a macro to access the 'gclist' field in different types.) -*/ -#define linkgclist(o,p) linkgclist_(obj2gco(o), &(o)->gclist, &(p)) - -static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) { - lua_assert(!isgray(o)); /* cannot be in a gray list */ - *pnext = *list; - *list = o; - set2gray(o); /* now it is */ -} - - -/* -** Link a generic collectable object 'o' into the list 'p'. -*/ -#define linkobjgclist(o,p) linkgclist_(obj2gco(o), getgclist(o), &(p)) - - - -/* -** Clear keys for empty entries in tables. If entry is empty, mark its -** entry as dead. This allows the collection of the key, but keeps its -** entry in the table: its removal could break a chain and could break -** a table traversal. Other places never manipulate dead keys, because -** its associated empty value is enough to signal that the entry is -** logically empty. -*/ -static void clearkey (Node *n) { - lua_assert(isempty(gval(n))); - if (keyiscollectable(n)) - setdeadkey(n); /* unused key; remove it */ -} - - -/* -** tells whether a key or value can be cleared from a weak -** table. Non-collectable objects are never removed from weak -** tables. Strings behave as 'values', so are never removed too. for -** other objects: if really collected, cannot keep them; for objects -** being finalized, keep them in keys, but not in values -*/ -static int iscleared (global_State *g, const GCObject *o) { - if (o == NULL) return 0; /* non-collectable value */ - else if (novariant(o->tt) == LUA_TSTRING) { - markobject(g, o); /* strings are 'values', so are never weak */ - return 0; - } - else return iswhite(o); -} - - -/* -** Barrier that moves collector forward, that is, marks the white object -** 'v' being pointed by the black object 'o'. In the generational -** mode, 'v' must also become old, if 'o' is old; however, it cannot -** be changed directly to OLD, because it may still point to non-old -** objects. So, it is marked as OLD0. In the next cycle it will become -** OLD1, and in the next it will finally become OLD (regular old). By -** then, any object it points to will also be old. If called in the -** incremental sweep phase, it clears the black object to white (sweep -** it) to avoid other barrier calls for this same object. (That cannot -** be done is generational mode, as its sweep does not distinguish -** whites from deads.) -*/ -void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { - global_State *g = G(L); - lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); - if (keepinvariant(g)) { /* must keep invariant? */ - reallymarkobject(g, v); /* restore invariant */ - if (isold(o)) { - lua_assert(!isold(v)); /* white object could not be old */ - setage(v, G_OLD0); /* restore generational invariant */ - } - } - else { /* sweep phase */ - lua_assert(issweepphase(g)); - if (g->gckind == KGC_INC) /* incremental mode? */ - makewhite(g, o); /* mark 'o' as white to avoid other barriers */ - } -} - - -/* -** barrier that moves collector backward, that is, mark the black object -** pointing to a white object as gray again. -*/ -void luaC_barrierback_ (lua_State *L, GCObject *o) { - global_State *g = G(L); - lua_assert(isblack(o) && !isdead(g, o)); - lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1)); - if (getage(o) == G_TOUCHED2) /* already in gray list? */ - set2gray(o); /* make it gray to become touched1 */ - else /* link it in 'grayagain' and paint it gray */ - linkobjgclist(o, g->grayagain); - if (isold(o)) /* generational mode? */ - setage(o, G_TOUCHED1); /* touched in current cycle */ -} - - -void luaC_fix (lua_State *L, GCObject *o) { - global_State *g = G(L); - lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ - set2gray(o); /* they will be gray forever */ - setage(o, G_OLD); /* and old forever */ - g->allgc = o->next; /* remove object from 'allgc' list */ - o->next = g->fixedgc; /* link it to 'fixedgc' list */ - g->fixedgc = o; -} - - -/* -** create a new collectable object (with given type and size) and link -** it to 'allgc' list. -*/ -GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { - global_State *g = G(L); - GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); - o->marked = luaC_white(g); - o->tt = tt; - o->next = g->allgc; - g->allgc = o; - return o; -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** Mark functions -** ======================================================= -*/ - - -/* -** Mark an object. Userdata with no user values, strings, and closed -** upvalues are visited and turned black here. Open upvalues are -** already indirectly linked through their respective threads in the -** 'twups' list, so they don't go to the gray list; nevertheless, they -** are kept gray to avoid barriers, as their values will be revisited -** by the thread or by 'remarkupvals'. Other objects are added to the -** gray list to be visited (and turned black) later. Both userdata and -** upvalues can call this function recursively, but this recursion goes -** for at most two levels: An upvalue cannot refer to another upvalue -** (only closures can), and a userdata's metatable must be a table. -*/ -static void reallymarkobject (global_State *g, GCObject *o) { - switch (o->tt) { - case LUA_VSHRSTR: - case LUA_VLNGSTR: { - set2black(o); /* nothing to visit */ - break; - } - case LUA_VUPVAL: { - UpVal *uv = gco2upv(o); - if (upisopen(uv)) - set2gray(uv); /* open upvalues are kept gray */ - else - set2black(uv); /* closed upvalues are visited here */ - markvalue(g, uv->v); /* mark its content */ - break; - } - case LUA_VUSERDATA: { - Udata *u = gco2u(o); - if (u->nuvalue == 0) { /* no user values? */ - markobjectN(g, u->metatable); /* mark its metatable */ - set2black(u); /* nothing else to mark */ - break; - } - /* else... */ - } /* FALLTHROUGH */ - case LUA_VLCL: case LUA_VCCL: case LUA_VTABLE: - case LUA_VTHREAD: case LUA_VPROTO: { - linkobjgclist(o, g->gray); /* to be visited later */ - break; - } - default: lua_assert(0); break; - } -} - - -/* -** mark metamethods for basic types -*/ -static void markmt (global_State *g) { - int i; - for (i=0; i < LUA_NUMTAGS; i++) - markobjectN(g, g->mt[i]); -} - - -/* -** mark all objects in list of being-finalized -*/ -static lu_mem markbeingfnz (global_State *g) { - GCObject *o; - lu_mem count = 0; - for (o = g->tobefnz; o != NULL; o = o->next) { - count++; - markobject(g, o); - } - return count; -} - - -/* -** For each non-marked thread, simulates a barrier between each open -** upvalue and its value. (If the thread is collected, the value will be -** assigned to the upvalue, but then it can be too late for the barrier -** to act. The "barrier" does not need to check colors: A non-marked -** thread must be young; upvalues cannot be older than their threads; so -** any visited upvalue must be young too.) Also removes the thread from -** the list, as it was already visited. Removes also threads with no -** upvalues, as they have nothing to be checked. (If the thread gets an -** upvalue later, it will be linked in the list again.) -*/ -static int remarkupvals (global_State *g) { - lua_State *thread; - lua_State **p = &g->twups; - int work = 0; /* estimate of how much work was done here */ - while ((thread = *p) != NULL) { - work++; - if (!iswhite(thread) && thread->openupval != NULL) - p = &thread->twups; /* keep marked thread with upvalues in the list */ - else { /* thread is not marked or without upvalues */ - UpVal *uv; - lua_assert(!isold(thread) || thread->openupval == NULL); - *p = thread->twups; /* remove thread from the list */ - thread->twups = thread; /* mark that it is out of list */ - for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { - lua_assert(getage(uv) <= getage(thread)); - work++; - if (!iswhite(uv)) { /* upvalue already visited? */ - lua_assert(upisopen(uv) && isgray(uv)); - markvalue(g, uv->v); /* mark its value */ - } - } - } - } - return work; -} - - -static void cleargraylists (global_State *g) { - g->gray = g->grayagain = NULL; - g->weak = g->allweak = g->ephemeron = NULL; -} - - -/* -** mark root set and reset all gray lists, to start a new collection -*/ -static void restartcollection (global_State *g) { - cleargraylists(g); - markobject(g, g->mainthread); - markvalue(g, &g->l_registry); - markmt(g); - markbeingfnz(g); /* mark any finalizing object left from previous cycle */ -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Traverse functions -** ======================================================= -*/ - - -/* -** Check whether object 'o' should be kept in the 'grayagain' list for -** post-processing by 'correctgraylist'. (It could put all old objects -** in the list and leave all the work to 'correctgraylist', but it is -** more efficient to avoid adding elements that will be removed.) Only -** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go -** back to a gray list, but then it must become OLD. (That is what -** 'correctgraylist' does when it finds a TOUCHED2 object.) -*/ -static void genlink (global_State *g, GCObject *o) { - lua_assert(isblack(o)); - if (getage(o) == G_TOUCHED1) { /* touched in this cycle? */ - linkobjgclist(o, g->grayagain); /* link it back in 'grayagain' */ - } /* everything else do not need to be linked back */ - else if (getage(o) == G_TOUCHED2) - changeage(o, G_TOUCHED2, G_OLD); /* advance age */ -} - - -/* -** Traverse a table with weak values and link it to proper list. During -** propagate phase, keep it in 'grayagain' list, to be revisited in the -** atomic phase. In the atomic phase, if table has any white value, -** put it in 'weak' list, to be cleared. -*/ -static void traverseweakvalue (global_State *g, Table *h) { - Node *n, *limit = gnodelast(h); - /* if there is array part, assume it may have white values (it is not - worth traversing it now just to check) */ - int hasclears = (h->alimit > 0); - for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ - if (isempty(gval(n))) /* entry is empty? */ - clearkey(n); /* clear its key */ - else { - lua_assert(!keyisnil(n)); - markkey(g, n); - if (!hasclears && iscleared(g, gcvalueN(gval(n)))) /* a white value? */ - hasclears = 1; /* table will have to be cleared */ - } - } - if (g->gcstate == GCSatomic && hasclears) - linkgclist(h, g->weak); /* has to be cleared later */ - else - linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ -} - - -/* -** Traverse an ephemeron table and link it to proper list. Returns true -** iff any object was marked during this traversal (which implies that -** convergence has to continue). During propagation phase, keep table -** in 'grayagain' list, to be visited again in the atomic phase. In -** the atomic phase, if table has any white->white entry, it has to -** be revisited during ephemeron convergence (as that key may turn -** black). Otherwise, if it has any white key, table has to be cleared -** (in the atomic phase). In generational mode, some tables -** must be kept in some gray list for post-processing; this is done -** by 'genlink'. -*/ -static int traverseephemeron (global_State *g, Table *h, int inv) { - int marked = 0; /* true if an object is marked in this traversal */ - int hasclears = 0; /* true if table has white keys */ - int hasww = 0; /* true if table has entry "white-key -> white-value" */ - unsigned int i; - unsigned int asize = luaH_realasize(h); - unsigned int nsize = sizenode(h); - /* traverse array part */ - for (i = 0; i < asize; i++) { - if (valiswhite(&h->array[i])) { - marked = 1; - reallymarkobject(g, gcvalue(&h->array[i])); - } - } - /* traverse hash part; if 'inv', traverse descending - (see 'convergeephemerons') */ - for (i = 0; i < nsize; i++) { - Node *n = inv ? gnode(h, nsize - 1 - i) : gnode(h, i); - if (isempty(gval(n))) /* entry is empty? */ - clearkey(n); /* clear its key */ - else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */ - hasclears = 1; /* table must be cleared */ - if (valiswhite(gval(n))) /* value not marked yet? */ - hasww = 1; /* white-white entry */ - } - else if (valiswhite(gval(n))) { /* value not marked yet? */ - marked = 1; - reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ - } - } - /* link table into proper list */ - if (g->gcstate == GCSpropagate) - linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ - else if (hasww) /* table has white->white entries? */ - linkgclist(h, g->ephemeron); /* have to propagate again */ - else if (hasclears) /* table has white keys? */ - linkgclist(h, g->allweak); /* may have to clean white keys */ - else - genlink(g, obj2gco(h)); /* check whether collector still needs to see it */ - return marked; -} - - -static void traversestrongtable (global_State *g, Table *h) { - Node *n, *limit = gnodelast(h); - unsigned int i; - unsigned int asize = luaH_realasize(h); - for (i = 0; i < asize; i++) /* traverse array part */ - markvalue(g, &h->array[i]); - for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ - if (isempty(gval(n))) /* entry is empty? */ - clearkey(n); /* clear its key */ - else { - lua_assert(!keyisnil(n)); - markkey(g, n); - markvalue(g, gval(n)); - } - } - genlink(g, obj2gco(h)); -} - - -static lu_mem traversetable (global_State *g, Table *h) { - const char *weakkey, *weakvalue; - const TValue *mode = gfasttm(g, h->metatable, TM_MODE); - markobjectN(g, h->metatable); - if (mode && ttisstring(mode) && /* is there a weak mode? */ - (cast_void(weakkey = strchr(svalue(mode), 'k')), - cast_void(weakvalue = strchr(svalue(mode), 'v')), - (weakkey || weakvalue))) { /* is really weak? */ - if (!weakkey) /* strong keys? */ - traverseweakvalue(g, h); - else if (!weakvalue) /* strong values? */ - traverseephemeron(g, h, 0); - else /* all weak */ - linkgclist(h, g->allweak); /* nothing to traverse now */ - } - else /* not weak */ - traversestrongtable(g, h); - return 1 + h->alimit + 2 * allocsizenode(h); -} - - -static int traverseudata (global_State *g, Udata *u) { - int i; - markobjectN(g, u->metatable); /* mark its metatable */ - for (i = 0; i < u->nuvalue; i++) - markvalue(g, &u->uv[i].uv); - genlink(g, obj2gco(u)); - return 1 + u->nuvalue; -} - - -/* -** 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; - markobjectN(g, f->source); - for (i = 0; i < f->sizek; i++) /* mark literals */ - markvalue(g, &f->k[i]); - for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ - 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 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; -} - - -static int traverseCclosure (global_State *g, CClosure *cl) { - int i; - for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ - markvalue(g, &cl->upvalue[i]); - return 1 + cl->nupvalues; -} - -/* -** Traverse a Lua closure, marking its prototype and its upvalues. -** (Both can be NULL while closure is being created.) -*/ -static int traverseLclosure (global_State *g, LClosure *cl) { - int i; - markobjectN(g, cl->p); /* mark its prototype */ - for (i = 0; i < cl->nupvalues; i++) { /* visit its upvalues */ - UpVal *uv = cl->upvals[i]; - markobjectN(g, uv); /* mark upvalue */ - } - return 1 + cl->nupvalues; -} - - -/* -** Traverse a thread, marking the elements in the stack up to its top -** and cleaning the rest of the stack in the final traversal. That -** ensures that the entire stack have valid (non-dead) objects. -** Threads have no barriers. In gen. mode, old threads must be visited -** at every cycle, because they might point to young objects. In inc. -** mode, the thread can still be modified before the end of the cycle, -** and therefore it must be visited again in the atomic phase. To ensure -** these visits, threads must return to a gray list if they are not new -** (which can only happen in generational mode) or if the traverse is in -** the propagate phase (which can only happen in incremental mode). -*/ -static int traversethread (global_State *g, lua_State *th) { - UpVal *uv; - StkId o = th->stack; - if (isold(th) || g->gcstate == GCSpropagate) - linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ - if (o == NULL) - return 1; /* stack not completely built yet */ - lua_assert(g->gcstate == GCSatomic || - th->openupval == NULL || isintwups(th)); - for (; o < th->top; o++) /* mark live elements in the stack */ - markvalue(g, s2v(o)); - for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) - markobject(g, uv); /* open upvalues cannot be collected */ - if (g->gcstate == GCSatomic) { /* final traversal? */ - for (; o < th->stack_last + EXTRA_STACK; o++) - setnilvalue(s2v(o)); /* clear dead stack slice */ - /* 'remarkupvals' may have removed thread from 'twups' list */ - if (!isintwups(th) && th->openupval != NULL) { - th->twups = g->twups; /* link it back to the list */ - g->twups = th; - } - } - else if (!g->gcemergency) - luaD_shrinkstack(th); /* do not change stack in emergency cycle */ - return 1 + stacksize(th); -} - - -/* -** traverse one gray object, turning it to black. -*/ -static lu_mem propagatemark (global_State *g) { - GCObject *o = g->gray; - nw2black(o); - g->gray = *getgclist(o); /* remove from 'gray' list */ - switch (o->tt) { - case LUA_VTABLE: return traversetable(g, gco2t(o)); - case LUA_VUSERDATA: return traverseudata(g, gco2u(o)); - case LUA_VLCL: return traverseLclosure(g, gco2lcl(o)); - case LUA_VCCL: return traverseCclosure(g, gco2ccl(o)); - case LUA_VPROTO: return traverseproto(g, gco2p(o)); - case LUA_VTHREAD: return traversethread(g, gco2th(o)); - default: lua_assert(0); return 0; - } -} - - -static lu_mem propagateall (global_State *g) { - lu_mem tot = 0; - while (g->gray) - tot += propagatemark(g); - return tot; -} - - -/* -** Traverse all ephemeron tables propagating marks from keys to values. -** Repeat until it converges, that is, nothing new is marked. 'dir' -** inverts the direction of the traversals, trying to speed up -** convergence on chains in the same table. -** -*/ -static void convergeephemerons (global_State *g) { - int changed; - int dir = 0; - do { - GCObject *w; - GCObject *next = g->ephemeron; /* get ephemeron list */ - g->ephemeron = NULL; /* tables may return to this list when traversed */ - changed = 0; - while ((w = next) != NULL) { /* for each ephemeron table */ - Table *h = gco2t(w); - next = h->gclist; /* list is rebuilt during loop */ - nw2black(h); /* out of the list (for now) */ - if (traverseephemeron(g, h, dir)) { /* marked some value? */ - propagateall(g); /* propagate changes */ - changed = 1; /* will have to revisit all ephemeron tables */ - } - } - dir = !dir; /* invert direction next time */ - } while (changed); /* repeat until no more changes */ -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Sweep Functions -** ======================================================= -*/ - - -/* -** clear entries with unmarked keys from all weaktables in list 'l' -*/ -static void clearbykeys (global_State *g, GCObject *l) { - for (; l; l = gco2t(l)->gclist) { - Table *h = gco2t(l); - Node *limit = gnodelast(h); - Node *n; - for (n = gnode(h, 0); n < limit; n++) { - if (iscleared(g, gckeyN(n))) /* unmarked key? */ - setempty(gval(n)); /* remove entry */ - if (isempty(gval(n))) /* is entry empty? */ - clearkey(n); /* clear its key */ - } - } -} - - -/* -** clear entries with unmarked values from all weaktables in list 'l' up -** to element 'f' -*/ -static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) { - for (; l != f; l = gco2t(l)->gclist) { - Table *h = gco2t(l); - Node *n, *limit = gnodelast(h); - unsigned int i; - unsigned int asize = luaH_realasize(h); - for (i = 0; i < asize; i++) { - TValue *o = &h->array[i]; - if (iscleared(g, gcvalueN(o))) /* value was collected? */ - setempty(o); /* remove entry */ - } - for (n = gnode(h, 0); n < limit; n++) { - if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ - setempty(gval(n)); /* remove entry */ - if (isempty(gval(n))) /* is entry empty? */ - clearkey(n); /* clear its key */ - } - } -} - - -static void freeupval (lua_State *L, UpVal *uv) { - if (upisopen(uv)) - luaF_unlinkupval(uv); - luaM_free(L, uv); -} - - -static void freeobj (lua_State *L, GCObject *o) { - switch (o->tt) { - case LUA_VPROTO: - luaF_freeproto(L, gco2p(o)); - break; - case LUA_VUPVAL: - freeupval(L, gco2upv(o)); - break; - case LUA_VLCL: { - LClosure *cl = gco2lcl(o); - luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); - break; - } - case LUA_VCCL: { - CClosure *cl = gco2ccl(o); - luaM_freemem(L, cl, sizeCclosure(cl->nupvalues)); - break; - } - case LUA_VTABLE: - luaH_free(L, gco2t(o)); - break; - case LUA_VTHREAD: - luaE_freethread(L, gco2th(o)); - break; - case LUA_VUSERDATA: { - Udata *u = gco2u(o); - luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); - break; - } - case LUA_VSHRSTR: { - TString *ts = gco2ts(o); - luaS_remove(L, ts); /* remove it from hash table */ - luaM_freemem(L, ts, sizelstring(ts->shrlen)); - break; - } - case LUA_VLNGSTR: { - TString *ts = gco2ts(o); - luaM_freemem(L, ts, sizelstring(ts->u.lnglen)); - break; - } - default: lua_assert(0); - } -} - - -/* -** sweep at most 'countin' elements from a list of GCObjects erasing dead -** objects, where a dead object is one marked with the old (non current) -** white; change all non-dead objects back to white, preparing for next -** collection cycle. Return where to continue the traversal or NULL if -** list is finished. ('*countout' gets the number of elements traversed.) -*/ -static GCObject **sweeplist (lua_State *L, GCObject **p, int countin, - int *countout) { - global_State *g = G(L); - int ow = otherwhite(g); - int i; - int white = luaC_white(g); /* current white */ - for (i = 0; *p != NULL && i < countin; i++) { - GCObject *curr = *p; - int marked = curr->marked; - if (isdeadm(ow, marked)) { /* is 'curr' dead? */ - *p = curr->next; /* remove 'curr' from list */ - freeobj(L, curr); /* erase 'curr' */ - } - else { /* change mark to 'white' */ - curr->marked = cast_byte((marked & ~maskgcbits) | white); - p = &curr->next; /* go to next element */ - } - } - if (countout) - *countout = i; /* number of elements traversed */ - return (*p == NULL) ? NULL : p; -} - - -/* -** sweep a list until a live object (or end of list) -*/ -static GCObject **sweeptolive (lua_State *L, GCObject **p) { - GCObject **old = p; - do { - p = sweeplist(L, p, 1, NULL); - } while (p == old); - return p; -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Finalization -** ======================================================= -*/ - -/* -** If possible, shrink string table. -*/ -static void checkSizes (lua_State *L, global_State *g) { - if (!g->gcemergency) { - if (g->strt.nuse < g->strt.size / 4) { /* string table too big? */ - l_mem olddebt = g->GCdebt; - luaS_resize(L, g->strt.size / 2); - g->GCestimate += g->GCdebt - olddebt; /* correct estimate */ - } - } -} - - -/* -** Get the next udata to be finalized from the 'tobefnz' list, and -** link it back into the 'allgc' list. -*/ -static GCObject *udata2finalize (global_State *g) { - GCObject *o = g->tobefnz; /* get first element */ - lua_assert(tofinalize(o)); - g->tobefnz = o->next; /* remove it from 'tobefnz' list */ - o->next = g->allgc; /* return it to 'allgc' list */ - g->allgc = o; - resetbit(o->marked, FINALIZEDBIT); /* object is "normal" again */ - if (issweepphase(g)) - makewhite(g, o); /* "sweep" object */ - else if (getage(o) == G_OLD1) - g->firstold1 = o; /* it is the first OLD1 object in the list */ - return o; -} - - -static void dothecall (lua_State *L, void *ud) { - UNUSED(ud); - luaD_callnoyield(L, L->top - 2, 0); -} - - -static void GCTM (lua_State *L) { - global_State *g = G(L); - const TValue *tm; - TValue v; - lua_assert(!g->gcemergency); - setgcovalue(L, &v, udata2finalize(g)); - tm = luaT_gettmbyobj(L, &v, TM_GC); - if (!notm(tm)) { /* is there a finalizer? */ - int status; - lu_byte oldah = L->allowhook; - int running = g->gcrunning; - L->allowhook = 0; /* stop debug hooks during GC metamethod */ - g->gcrunning = 0; /* avoid GC steps */ - setobj2s(L, L->top++, tm); /* push finalizer... */ - setobj2s(L, L->top++, &v); /* ... and its argument */ - L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ - status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); - L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ - L->allowhook = oldah; /* restore hooks */ - g->gcrunning = running; /* restore state */ - if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ - luaE_warnerror(L, "__gc metamethod"); - L->top--; /* pops error object */ - } - } -} - - -/* -** Call a few finalizers -*/ -static int runafewfinalizers (lua_State *L, int n) { - global_State *g = G(L); - int i; - for (i = 0; i < n && g->tobefnz; i++) - GCTM(L); /* call one finalizer */ - return i; -} - - -/* -** call all pending finalizers -*/ -static void callallpendingfinalizers (lua_State *L) { - global_State *g = G(L); - while (g->tobefnz) - GCTM(L); -} - - -/* -** find last 'next' field in list 'p' list (to add elements in its end) -*/ -static GCObject **findlast (GCObject **p) { - while (*p != NULL) - p = &(*p)->next; - return p; -} - - -/* -** Move all unreachable objects (or 'all' objects) that need -** finalization from list 'finobj' to list 'tobefnz' (to be finalized). -** (Note that objects after 'finobjold1' cannot be white, so they -** don't need to be traversed. In incremental mode, 'finobjold1' is NULL, -** so the whole list is traversed.) -*/ -static void separatetobefnz (global_State *g, int all) { - GCObject *curr; - GCObject **p = &g->finobj; - GCObject **lastnext = findlast(&g->tobefnz); - while ((curr = *p) != g->finobjold1) { /* traverse all finalizable objects */ - lua_assert(tofinalize(curr)); - if (!(iswhite(curr) || all)) /* not being collected? */ - p = &curr->next; /* don't bother with it */ - else { - if (curr == g->finobjsur) /* removing 'finobjsur'? */ - g->finobjsur = curr->next; /* correct it */ - *p = curr->next; /* remove 'curr' from 'finobj' list */ - curr->next = *lastnext; /* link at the end of 'tobefnz' list */ - *lastnext = curr; - lastnext = &curr->next; - } - } -} - - -/* -** If pointer 'p' points to 'o', move it to the next element. -*/ -static void checkpointer (GCObject **p, GCObject *o) { - if (o == *p) - *p = o->next; -} - - -/* -** Correct pointers to objects inside 'allgc' list when -** object 'o' is being removed from the list. -*/ -static void correctpointers (global_State *g, GCObject *o) { - checkpointer(&g->survival, o); - checkpointer(&g->old1, o); - checkpointer(&g->reallyold, o); - checkpointer(&g->firstold1, o); -} - - -/* -** if object 'o' has a finalizer, remove it from 'allgc' list (must -** search the list to find it) and link it in 'finobj' list. -*/ -void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { - global_State *g = G(L); - if (tofinalize(o) || /* obj. is already marked... */ - gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ - return; /* nothing to be done */ - else { /* move 'o' to 'finobj' list */ - GCObject **p; - if (issweepphase(g)) { - makewhite(g, o); /* "sweep" object 'o' */ - if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */ - g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */ - } - else - correctpointers(g, o); - /* search for pointer pointing to 'o' */ - for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ } - *p = o->next; /* remove 'o' from 'allgc' list */ - o->next = g->finobj; /* link it in 'finobj' list */ - g->finobj = o; - l_setbit(o->marked, FINALIZEDBIT); /* mark it as such */ - } -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Generational Collector -** ======================================================= -*/ - -static void setpause (global_State *g); - - -/* -** Sweep a list of objects to enter generational mode. Deletes dead -** objects and turns the non dead to old. All non-dead threads---which -** are now old---must be in a gray list. Everything else is not in a -** gray list. Open upvalues are also kept gray. -*/ -static void sweep2old (lua_State *L, GCObject **p) { - GCObject *curr; - global_State *g = G(L); - while ((curr = *p) != NULL) { - if (iswhite(curr)) { /* is 'curr' dead? */ - lua_assert(isdead(g, curr)); - *p = curr->next; /* remove 'curr' from list */ - freeobj(L, curr); /* erase 'curr' */ - } - else { /* all surviving objects become old */ - setage(curr, G_OLD); - if (curr->tt == LUA_VTHREAD) { /* threads must be watched */ - lua_State *th = gco2th(curr); - linkgclist(th, g->grayagain); /* insert into 'grayagain' list */ - } - else if (curr->tt == LUA_VUPVAL && upisopen(gco2upv(curr))) - set2gray(curr); /* open upvalues are always gray */ - else /* everything else is black */ - nw2black(curr); - p = &curr->next; /* go to next element */ - } - } -} - - -/* -** Sweep for generational mode. Delete dead objects. (Because the -** collection is not incremental, there are no "new white" objects -** during the sweep. So, any white object must be dead.) For -** non-dead objects, advance their ages and clear the color of -** new objects. (Old objects keep their colors.) -** The ages of G_TOUCHED1 and G_TOUCHED2 objects cannot be advanced -** here, because these old-generation objects are usually not swept -** here. They will all be advanced in 'correctgraylist'. That function -** will also remove objects turned white here from any gray list. -*/ -static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, - GCObject *limit, GCObject **pfirstold1) { - static const lu_byte nextage[] = { - G_SURVIVAL, /* from G_NEW */ - G_OLD1, /* from G_SURVIVAL */ - G_OLD1, /* from G_OLD0 */ - G_OLD, /* from G_OLD1 */ - G_OLD, /* from G_OLD (do not change) */ - G_TOUCHED1, /* from G_TOUCHED1 (do not change) */ - G_TOUCHED2 /* from G_TOUCHED2 (do not change) */ - }; - int white = luaC_white(g); - GCObject *curr; - while ((curr = *p) != limit) { - if (iswhite(curr)) { /* is 'curr' dead? */ - lua_assert(!isold(curr) && isdead(g, curr)); - *p = curr->next; /* remove 'curr' from list */ - freeobj(L, curr); /* erase 'curr' */ - } - else { /* correct mark and age */ - if (getage(curr) == G_NEW) { /* new objects go back to white */ - int marked = curr->marked & ~maskgcbits; /* erase GC bits */ - curr->marked = cast_byte(marked | G_SURVIVAL | white); - } - else { /* all other objects will be old, and so keep their color */ - setage(curr, nextage[getage(curr)]); - if (getage(curr) == G_OLD1 && *pfirstold1 == NULL) - *pfirstold1 = curr; /* first OLD1 object in the list */ - } - p = &curr->next; /* go to next element */ - } - } - return p; -} - - -/* -** Traverse a list making all its elements white and clearing their -** age. In incremental mode, all objects are 'new' all the time, -** except for fixed strings (which are always old). -*/ -static void whitelist (global_State *g, GCObject *p) { - int white = luaC_white(g); - for (; p != NULL; p = p->next) - p->marked = cast_byte((p->marked & ~maskgcbits) | white); -} - - -/* -** Correct a list of gray objects. Return pointer to where rest of the -** list should be linked. -** Because this correction is done after sweeping, young objects might -** be turned white and still be in the list. They are only removed. -** 'TOUCHED1' objects are advanced to 'TOUCHED2' and remain on the list; -** Non-white threads also remain on the list; 'TOUCHED2' objects become -** regular old; they and anything else are removed from the list. -*/ -static GCObject **correctgraylist (GCObject **p) { - GCObject *curr; - while ((curr = *p) != NULL) { - GCObject **next = getgclist(curr); - if (iswhite(curr)) - goto remove; /* remove all white objects */ - else if (getage(curr) == G_TOUCHED1) { /* touched in this cycle? */ - lua_assert(isgray(curr)); - nw2black(curr); /* make it black, for next barrier */ - changeage(curr, G_TOUCHED1, G_TOUCHED2); - goto remain; /* keep it in the list and go to next element */ - } - else if (curr->tt == LUA_VTHREAD) { - lua_assert(isgray(curr)); - goto remain; /* keep non-white threads on the list */ - } - else { /* everything else is removed */ - lua_assert(isold(curr)); /* young objects should be white here */ - if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */ - changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ - nw2black(curr); /* make object black (to be removed) */ - goto remove; - } - remove: *p = *next; continue; - remain: p = next; continue; - } - return p; -} - - -/* -** Correct all gray lists, coalescing them into 'grayagain'. -*/ -static void correctgraylists (global_State *g) { - GCObject **list = correctgraylist(&g->grayagain); - *list = g->weak; g->weak = NULL; - list = correctgraylist(list); - *list = g->allweak; g->allweak = NULL; - list = correctgraylist(list); - *list = g->ephemeron; g->ephemeron = NULL; - correctgraylist(list); -} - - -/* -** Mark black 'OLD1' objects when starting a new young collection. -** Gray objects are already in some gray list, and so will be visited -** in the atomic step. -*/ -static void markold (global_State *g, GCObject *from, GCObject *to) { - GCObject *p; - for (p = from; p != to; p = p->next) { - if (getage(p) == G_OLD1) { - lua_assert(!iswhite(p)); - changeage(p, G_OLD1, G_OLD); /* now they are old */ - if (isblack(p)) - reallymarkobject(g, p); - } - } -} - - -/* -** Finish a young-generation collection. -*/ -static void finishgencycle (lua_State *L, global_State *g) { - correctgraylists(g); - checkSizes(L, g); - g->gcstate = GCSpropagate; /* skip restart */ - if (!g->gcemergency) - callallpendingfinalizers(L); -} - - -/* -** Does a young collection. First, mark 'OLD1' objects. Then does the -** atomic step. Then, sweep all lists and advance pointers. Finally, -** finish the collection. -*/ -static void youngcollection (lua_State *L, global_State *g) { - GCObject **psurvival; /* to point to first non-dead survival object */ - GCObject *dummy; /* dummy out parameter to 'sweepgen' */ - lua_assert(g->gcstate == GCSpropagate); - if (g->firstold1) { /* are there regular OLD1 objects? */ - markold(g, g->firstold1, g->reallyold); /* mark them */ - g->firstold1 = NULL; /* no more OLD1 objects (for now) */ - } - markold(g, g->finobj, g->finobjrold); - markold(g, g->tobefnz, NULL); - atomic(L); - - /* sweep nursery and get a pointer to its last live element */ - g->gcstate = GCSswpallgc; - psurvival = sweepgen(L, g, &g->allgc, g->survival, &g->firstold1); - /* sweep 'survival' */ - sweepgen(L, g, psurvival, g->old1, &g->firstold1); - g->reallyold = g->old1; - g->old1 = *psurvival; /* 'survival' survivals are old now */ - g->survival = g->allgc; /* all news are survivals */ - - /* repeat for 'finobj' lists */ - dummy = NULL; /* no 'firstold1' optimization for 'finobj' lists */ - psurvival = sweepgen(L, g, &g->finobj, g->finobjsur, &dummy); - /* sweep 'survival' */ - sweepgen(L, g, psurvival, g->finobjold1, &dummy); - g->finobjrold = g->finobjold1; - g->finobjold1 = *psurvival; /* 'survival' survivals are old now */ - g->finobjsur = g->finobj; /* all news are survivals */ - - sweepgen(L, g, &g->tobefnz, NULL, &dummy); - finishgencycle(L, g); -} - - -/* -** Clears all gray lists, sweeps objects, and prepare sublists to enter -** generational mode. The sweeps remove dead objects and turn all -** surviving objects to old. Threads go back to 'grayagain'; everything -** else is turned black (not in any gray list). -*/ -static void atomic2gen (lua_State *L, global_State *g) { - cleargraylists(g); - /* sweep all elements making them old */ - g->gcstate = GCSswpallgc; - sweep2old(L, &g->allgc); - /* everything alive now is old */ - g->reallyold = g->old1 = g->survival = g->allgc; - g->firstold1 = NULL; /* there are no OLD1 objects anywhere */ - - /* repeat for 'finobj' lists */ - sweep2old(L, &g->finobj); - g->finobjrold = g->finobjold1 = g->finobjsur = g->finobj; - - sweep2old(L, &g->tobefnz); - - g->gckind = KGC_GEN; - g->lastatomic = 0; - g->GCestimate = gettotalbytes(g); /* base for memory control */ - finishgencycle(L, g); -} - - -/* -** Enter generational mode. Must go until the end of an atomic cycle -** to ensure that all objects are correctly marked and weak tables -** are cleared. Then, turn all objects into old and finishes the -** collection. -*/ -static lu_mem entergen (lua_State *L, global_State *g) { - lu_mem numobjs; - luaC_runtilstate(L, bitmask(GCSpause)); /* prepare to start a new cycle */ - luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ - numobjs = atomic(L); /* propagates all and then do the atomic stuff */ - atomic2gen(L, g); - return numobjs; -} - - -/* -** Enter incremental mode. Turn all objects white, make all -** intermediate lists point to NULL (to avoid invalid pointers), -** and go to the pause state. -*/ -static void enterinc (global_State *g) { - whitelist(g, g->allgc); - g->reallyold = g->old1 = g->survival = NULL; - whitelist(g, g->finobj); - whitelist(g, g->tobefnz); - g->finobjrold = g->finobjold1 = g->finobjsur = NULL; - g->gcstate = GCSpause; - g->gckind = KGC_INC; - g->lastatomic = 0; -} - - -/* -** Change collector mode to 'newmode'. -*/ -void luaC_changemode (lua_State *L, int newmode) { - global_State *g = G(L); - if (newmode != g->gckind) { - if (newmode == KGC_GEN) /* entering generational mode? */ - entergen(L, g); - else - enterinc(g); /* entering incremental mode */ - } - g->lastatomic = 0; -} - - -/* -** Does a full collection in generational mode. -*/ -static lu_mem fullgen (lua_State *L, global_State *g) { - enterinc(g); - return entergen(L, g); -} - - -/* -** Set debt for the next minor collection, which will happen when -** memory grows 'genminormul'%. -*/ -static void setminordebt (global_State *g) { - luaE_setdebt(g, -(cast(l_mem, (gettotalbytes(g) / 100)) * g->genminormul)); -} - - -/* -** Does a major collection after last collection was a "bad collection". -** -** When the program is building a big structure, it allocates lots of -** memory but generates very little garbage. In those scenarios, -** the generational mode just wastes time doing small collections, and -** major collections are frequently what we call a "bad collection", a -** collection that frees too few objects. To avoid the cost of switching -** between generational mode and the incremental mode needed for full -** (major) collections, the collector tries to stay in incremental mode -** after a bad collection, and to switch back to generational mode only -** after a "good" collection (one that traverses less than 9/8 objects -** of the previous one). -** The collector must choose whether to stay in incremental mode or to -** switch back to generational mode before sweeping. At this point, it -** does not know the real memory in use, so it cannot use memory to -** decide whether to return to generational mode. Instead, it uses the -** number of objects traversed (returned by 'atomic') as a proxy. The -** field 'g->lastatomic' keeps this count from the last collection. -** ('g->lastatomic != 0' also means that the last collection was bad.) -*/ -static void stepgenfull (lua_State *L, global_State *g) { - lu_mem newatomic; /* count of traversed objects */ - lu_mem lastatomic = g->lastatomic; /* count from last collection */ - if (g->gckind == KGC_GEN) /* still in generational mode? */ - enterinc(g); /* enter incremental mode */ - luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ - newatomic = atomic(L); /* mark everybody */ - if (newatomic < lastatomic + (lastatomic >> 3)) { /* good collection? */ - atomic2gen(L, g); /* return to generational mode */ - setminordebt(g); - } - else { /* another bad collection; stay in incremental mode */ - g->GCestimate = gettotalbytes(g); /* first estimate */; - entersweep(L); - luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ - setpause(g); - g->lastatomic = newatomic; - } -} - - -/* -** Does a generational "step". -** Usually, this means doing a minor collection and setting the debt to -** make another collection when memory grows 'genminormul'% larger. -** -** However, there are exceptions. If memory grows 'genmajormul'% -** larger than it was at the end of the last major collection (kept -** in 'g->GCestimate'), the function does a major collection. At the -** end, it checks whether the major collection was able to free a -** decent amount of memory (at least half the growth in memory since -** previous major collection). If so, the collector keeps its state, -** and the next collection will probably be minor again. Otherwise, -** we have what we call a "bad collection". In that case, set the field -** 'g->lastatomic' to signal that fact, so that the next collection will -** go to 'stepgenfull'. -** -** 'GCdebt <= 0' means an explicit call to GC step with "size" zero; -** in that case, do a minor collection. -*/ -static void genstep (lua_State *L, global_State *g) { - if (g->lastatomic != 0) /* last collection was a bad one? */ - stepgenfull(L, g); /* do a full step */ - else { - lu_mem majorbase = g->GCestimate; /* memory after last major collection */ - lu_mem majorinc = (majorbase / 100) * getgcparam(g->genmajormul); - if (g->GCdebt > 0 && gettotalbytes(g) > majorbase + majorinc) { - lu_mem numobjs = fullgen(L, g); /* do a major collection */ - if (gettotalbytes(g) < majorbase + (majorinc / 2)) { - /* collected at least half of memory growth since last major - collection; keep doing minor collections */ - setminordebt(g); - } - else { /* bad collection */ - g->lastatomic = numobjs; /* signal that last collection was bad */ - setpause(g); /* do a long wait for next (major) collection */ - } - } - else { /* regular case; do a minor collection */ - youngcollection(L, g); - setminordebt(g); - g->GCestimate = majorbase; /* preserve base value */ - } - } - lua_assert(isdecGCmodegen(g)); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** GC control -** ======================================================= -*/ - - -/* -** Set the "time" to wait before starting a new GC cycle; cycle will -** start when memory use hits the threshold of ('estimate' * pause / -** PAUSEADJ). (Division by 'estimate' should be OK: it cannot be zero, -** because Lua cannot even start with less than PAUSEADJ bytes). -*/ -static void setpause (global_State *g) { - l_mem threshold, debt; - int pause = getgcparam(g->gcpause); - l_mem estimate = g->GCestimate / PAUSEADJ; /* adjust 'estimate' */ - lua_assert(estimate > 0); - threshold = (pause < MAX_LMEM / estimate) /* overflow? */ - ? estimate * pause /* no overflow */ - : MAX_LMEM; /* overflow; truncate to maximum */ - debt = gettotalbytes(g) - threshold; - if (debt > 0) debt = 0; - luaE_setdebt(g, debt); -} - - -/* -** Enter first sweep phase. -** The call to 'sweeptolive' makes the pointer point to an object -** inside the list (instead of to the header), so that the real sweep do -** not need to skip objects created between "now" and the start of the -** real sweep. -*/ -static void entersweep (lua_State *L) { - global_State *g = G(L); - g->gcstate = GCSswpallgc; - lua_assert(g->sweepgc == NULL); - g->sweepgc = sweeptolive(L, &g->allgc); -} - - -/* -** Delete all objects in list 'p' until (but not including) object -** 'limit'. -*/ -static void deletelist (lua_State *L, GCObject *p, GCObject *limit) { - while (p != limit) { - GCObject *next = p->next; - freeobj(L, p); - p = next; - } -} - - -/* -** Call all finalizers of the objects in the given Lua state, and -** then free all objects, except for the main thread. -*/ -void luaC_freeallobjects (lua_State *L) { - global_State *g = G(L); - luaC_changemode(L, KGC_INC); - separatetobefnz(g, 1); /* separate all objects with finalizers */ - lua_assert(g->finobj == NULL); - callallpendingfinalizers(L); - deletelist(L, g->allgc, obj2gco(g->mainthread)); - deletelist(L, g->finobj, NULL); - deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ - lua_assert(g->strt.nuse == 0); -} - - -static lu_mem atomic (lua_State *L) { - global_State *g = G(L); - lu_mem work = 0; - GCObject *origweak, *origall; - GCObject *grayagain = g->grayagain; /* save original list */ - g->grayagain = NULL; - lua_assert(g->ephemeron == NULL && g->weak == NULL); - lua_assert(!iswhite(g->mainthread)); - g->gcstate = GCSatomic; - markobject(g, L); /* mark running thread */ - /* registry and global metatables may be changed by API */ - markvalue(g, &g->l_registry); - markmt(g); /* mark global metatables */ - work += propagateall(g); /* empties 'gray' list */ - /* remark occasional upvalues of (maybe) dead threads */ - work += remarkupvals(g); - work += propagateall(g); /* propagate changes */ - g->gray = grayagain; - work += propagateall(g); /* traverse 'grayagain' list */ - convergeephemerons(g); - /* at this point, all strongly accessible objects are marked. */ - /* Clear values from weak tables, before checking finalizers */ - clearbyvalues(g, g->weak, NULL); - clearbyvalues(g, g->allweak, NULL); - origweak = g->weak; origall = g->allweak; - separatetobefnz(g, 0); /* separate objects to be finalized */ - work += markbeingfnz(g); /* mark objects that will be finalized */ - work += propagateall(g); /* remark, to propagate 'resurrection' */ - convergeephemerons(g); - /* at this point, all resurrected objects are marked. */ - /* remove dead objects from weak tables */ - clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ - clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */ - /* clear values from resurrected weak tables */ - clearbyvalues(g, g->weak, origweak); - clearbyvalues(g, g->allweak, origall); - luaS_clearcache(g); - g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ - lua_assert(g->gray == NULL); - return work; /* estimate of slots marked by 'atomic' */ -} - - -static int sweepstep (lua_State *L, global_State *g, - int nextstate, GCObject **nextlist) { - if (g->sweepgc) { - l_mem olddebt = g->GCdebt; - int count; - g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX, &count); - g->GCestimate += g->GCdebt - olddebt; /* update estimate */ - return count; - } - else { /* enter next state */ - g->gcstate = nextstate; - g->sweepgc = nextlist; - return 0; /* no work done */ - } -} - - -static lu_mem singlestep (lua_State *L) { - global_State *g = G(L); - lu_mem work; - lua_assert(!g->gcstopem); /* collector is not reentrant */ - g->gcstopem = 1; /* no emergency collections while collecting */ - switch (g->gcstate) { - case GCSpause: { - restartcollection(g); - g->gcstate = GCSpropagate; - work = 1; - break; - } - case GCSpropagate: { - if (g->gray == NULL) { /* no more gray objects? */ - g->gcstate = GCSenteratomic; /* finish propagate phase */ - work = 0; - } - else - work = propagatemark(g); /* traverse one gray object */ - break; - } - case GCSenteratomic: { - work = atomic(L); /* work is what was traversed by 'atomic' */ - entersweep(L); - g->GCestimate = gettotalbytes(g); /* first estimate */; - break; - } - case GCSswpallgc: { /* sweep "regular" objects */ - work = sweepstep(L, g, GCSswpfinobj, &g->finobj); - break; - } - case GCSswpfinobj: { /* sweep objects with finalizers */ - work = sweepstep(L, g, GCSswptobefnz, &g->tobefnz); - break; - } - case GCSswptobefnz: { /* sweep objects to be finalized */ - work = sweepstep(L, g, GCSswpend, NULL); - break; - } - case GCSswpend: { /* finish sweeps */ - checkSizes(L, g); - g->gcstate = GCScallfin; - work = 0; - break; - } - case GCScallfin: { /* call remaining finalizers */ - if (g->tobefnz && !g->gcemergency) { - g->gcstopem = 0; /* ok collections during finalizers */ - work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; - } - else { /* emergency mode or no more finalizers */ - g->gcstate = GCSpause; /* finish collection */ - work = 0; - } - break; - } - default: lua_assert(0); return 0; - } - g->gcstopem = 0; - return work; -} - - -/* -** advances the garbage collector until it reaches a state allowed -** by 'statemask' -*/ -void luaC_runtilstate (lua_State *L, int statesmask) { - global_State *g = G(L); - while (!testbit(statesmask, g->gcstate)) - singlestep(L); -} - - -/* -** Performs a basic incremental step. The debt and step size are -** converted from bytes to "units of work"; then the function loops -** running single steps until adding that many units of work or -** finishing a cycle (pause state). Finally, it sets the debt that -** controls when next step will be performed. -*/ -static void incstep (lua_State *L, global_State *g) { - int stepmul = (getgcparam(g->gcstepmul) | 1); /* avoid division by 0 */ - l_mem debt = (g->GCdebt / WORK2MEM) * stepmul; - l_mem stepsize = (g->gcstepsize <= log2maxs(l_mem)) - ? ((cast(l_mem, 1) << g->gcstepsize) / WORK2MEM) * stepmul - : MAX_LMEM; /* overflow; keep maximum value */ - do { /* repeat until pause or enough "credit" (negative debt) */ - lu_mem work = singlestep(L); /* perform one single step */ - debt -= work; - } while (debt > -stepsize && g->gcstate != GCSpause); - if (g->gcstate == GCSpause) - setpause(g); /* pause until next cycle */ - else { - debt = (debt / stepmul) * WORK2MEM; /* convert 'work units' to bytes */ - luaE_setdebt(g, debt); - } -} - -/* -** performs a basic GC step if collector is running -*/ -void luaC_step (lua_State *L) { - global_State *g = G(L); - lua_assert(!g->gcemergency); - if (g->gcrunning) { /* running? */ - if(isdecGCmodegen(g)) - genstep(L, g); - else - incstep(L, g); - } -} - - -/* -** Perform a full collection in incremental mode. -** Before running the collection, check 'keepinvariant'; if it is true, -** there may be some objects marked as black, so the collector has -** to sweep all objects to turn them back to white (as white has not -** changed, nothing will be collected). -*/ -static void fullinc (lua_State *L, global_State *g) { - if (keepinvariant(g)) /* black objects? */ - entersweep(L); /* sweep everything to turn them back to white */ - /* finish any pending sweep phase to start a new cycle */ - luaC_runtilstate(L, bitmask(GCSpause)); - luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ - /* estimate must be correct after a full GC cycle */ - lua_assert(g->GCestimate == gettotalbytes(g)); - luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ - setpause(g); -} - - -/* -** Performs a full GC cycle; if 'isemergency', set a flag to avoid -** some operations which could change the interpreter state in some -** unexpected ways (running finalizers and shrinking some structures). -*/ -void luaC_fullgc (lua_State *L, int isemergency) { - global_State *g = G(L); - lua_assert(!g->gcemergency); - g->gcemergency = isemergency; /* set flag */ - if (g->gckind == KGC_INC) - fullinc(L, g); - else - fullgen(L, g); - g->gcemergency = 0; -} - -/* }====================================================== */ - - diff --git a/source/external/lua/lgc.h b/source/external/lua/lgc.h index 073e2a4..ee05417 100644 --- a/source/external/lua/lgc.h +++ b/source/external/lua/lgc.h @@ -8,6 +8,9 @@ #define lgc_h +#include + + #include "lobject.h" #include "lstate.h" @@ -20,8 +23,9 @@ ** never point to a white one. Moreover, any gray object must be in a ** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it ** can be visited again before finishing the collection cycle. (Open -** upvalues are an exception to this rule.) These lists have no meaning -** when the invariant is not being enforced (e.g., sweep phase). +** upvalues are an exception to this rule, as they are attached to +** a corresponding thread.) These lists have no meaning when the +** invariant is not being enforced (e.g., sweep phase). */ @@ -45,10 +49,10 @@ /* ** macro to tell when main invariant (white objects cannot point to black -** ones) must be kept. During a collection, the sweep -** phase may break the invariant, as objects turned white may point to -** still-black objects. The invariant is restored when sweep ends and -** all objects are white again. +** ones) must be kept. During a collection, the sweep phase may break +** the invariant, as objects turned white may point to still-black +** objects. The invariant is restored when sweep ends and all objects +** are white again. */ #define keepinvariant(g) ((g)->gcstate <= GCSatomic) @@ -117,69 +121,144 @@ #define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) #define isold(o) (getage(o) > G_SURVIVAL) -#define changeage(o,f,t) \ - check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) + +/* +** In generational mode, objects are created 'new'. After surviving one +** cycle, they become 'survival'. Both 'new' and 'survival' can point +** to any other object, as they are traversed at the end of the cycle. +** We call them both 'young' objects. +** If a survival object survives another cycle, it becomes 'old1'. +** 'old1' objects can still point to survival objects (but not to +** new objects), so they still must be traversed. After another cycle +** (that, being old, 'old1' objects will "survive" no matter what) +** finally the 'old1' object becomes really 'old', and then they +** are no more traversed. +** +** To keep its invariants, the generational mode uses the same barriers +** also used by the incremental mode. If a young object is caught in a +** forward barrier, it cannot become old immediately, because it can +** still point to other young objects. Instead, it becomes 'old0', +** which in the next cycle becomes 'old1'. So, 'old0' objects is +** old but can point to new and survival objects; 'old1' is old +** but cannot point to new objects; and 'old' cannot point to any +** young object. +** +** If any old object ('old0', 'old1', 'old') is caught in a back +** barrier, it becomes 'touched1' and goes into a gray list, to be +** visited at the end of the cycle. There it evolves to 'touched2', +** which can point to survivals but not to new objects. In yet another +** cycle then it becomes 'old' again. +** +** The generational mode must also control the colors of objects, +** because of the barriers. While the mutator is running, young objects +** are kept white. 'old', 'old1', and 'touched2' objects are kept black, +** as they cannot point to new objects; exceptions are threads and open +** upvalues, which age to 'old1' and 'old' but are kept gray. 'old0' +** objects may be gray or black, as in the incremental mode. 'touched1' +** objects are kept gray, as they must be visited again at the end of +** the cycle. +*/ -/* Default Values for GC parameters */ -#define LUAI_GENMAJORMUL 100 +/* +** {====================================================== +** Default Values for GC parameters +** ======================================================= +*/ + +/* +** Minor collections will shift to major ones after LUAI_MINORMAJOR% +** bytes become old. +*/ +#define LUAI_MINORMAJOR 70 + +/* +** Major collections will shift to minor ones after a collection +** collects at least LUAI_MAJORMINOR% of the new bytes. +*/ +#define LUAI_MAJORMINOR 50 + +/* +** A young (minor) collection will run after creating LUAI_GENMINORMUL% +** new bytes. +*/ #define LUAI_GENMINORMUL 20 -/* wait memory to double before starting new cycle */ -#define LUAI_GCPAUSE 200 + +/* incremental */ + +/* Number of bytes must be LUAI_GCPAUSE% before starting new cycle */ +#define LUAI_GCPAUSE 250 /* -** some gc parameters are stored divided by 4 to allow a maximum value -** up to 1023 in a 'lu_byte'. +** Step multiplier: The collector handles LUAI_GCMUL% work units for +** each new allocated word. (Each "work unit" corresponds roughly to +** sweeping one object or traversing one slot.) */ -#define getgcparam(p) ((p) * 4) -#define setgcparam(p,v) ((p) = (v) / 4) +#define LUAI_GCMUL 200 -#define LUAI_GCMUL 100 +/* How many bytes to allocate before next GC step */ +#define LUAI_GCSTEPSIZE (200 * sizeof(Table)) -/* how much to allocate before next GC step (log2) */ -#define LUAI_GCSTEPSIZE 13 /* 8 KB */ + +#define setgcparam(g,p,v) (g->gcparams[LUA_GCP##p] = luaO_codeparam(v)) +#define applygcparam(g,p,x) luaO_applyparam(g->gcparams[LUA_GCP##p], x) + +/* }====================================================== */ /* -** Check whether the declared GC mode is generational. While in -** generational mode, the collector can go temporarily to incremental -** mode to improve performance. This is signaled by 'g->lastatomic != 0'. +** Control when GC is running: */ -#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) +#define GCSTPUSR 1 /* bit true when GC stopped by user */ +#define GCSTPGC 2 /* bit true when GC stopped by itself */ +#define GCSTPCLS 4 /* bit true when closing Lua state */ +#define gcrunning(g) ((g)->gcstp == 0) + /* -** Does one step of collection when debt becomes positive. 'pre'/'pos' +** Does one step of collection when debt becomes zero. 'pre'/'pos' ** allows some adjustments to be done only when needed. macro ** 'condchangemem' is used only for heavy tests (forcing a full ** GC cycle on every opportunity) */ + +#if !defined(HARDMEMTESTS) +#define condchangemem(L,pre,pos,emg) ((void)0) +#else +#define condchangemem(L,pre,pos,emg) \ + { if (gcrunning(G(L))) { pre; luaC_fullgc(L, emg); pos; } } +#endif + #define luaC_condGC(L,pre,pos) \ - { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ - condchangemem(L,pre,pos); } + { if (G(L)->GCdebt <= 0) { pre; luaC_step(L); pos;}; \ + condchangemem(L,pre,pos,0); } /* more often than not, 'pre'/'pos' are empty */ #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) -#define luaC_barrier(L,p,v) ( \ - (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ - luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) - -#define luaC_barrierback(L,p,v) ( \ - (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ - luaC_barrierback_(L,p) : cast_void(0)) - #define luaC_objbarrier(L,p,o) ( \ (isblack(p) && iswhite(o)) ? \ luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) +#define luaC_barrier(L,p,v) ( \ + iscollectable(v) ? luaC_objbarrier(L,p,gcvalue(v)) : cast_void(0)) + +#define luaC_objbarrierback(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? luaC_barrierback_(L,p) : cast_void(0)) + +#define luaC_barrierback(L,p,v) ( \ + iscollectable(v) ? luaC_objbarrierback(L, p, gcvalue(v)) : cast_void(0)) + LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); LUAI_FUNC void luaC_freeallobjects (lua_State *L); LUAI_FUNC void luaC_step (lua_State *L); -LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int state, int fast); LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); -LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, lu_byte tt, size_t sz); +LUAI_FUNC GCObject *luaC_newobjdt (lua_State *L, lu_byte tt, size_t sz, + size_t offset); LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); diff --git a/source/external/lua/liblua.a b/source/external/lua/liblua.a new file mode 100644 index 0000000000000000000000000000000000000000..6282335a56cc9ff0f5d1447d8519353d90556ad2 GIT binary patch literal 606438 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

h^_1g523R?8s>4llMmXNjS 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

(boZ}_-^DJfRj1v_5@QhQw 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

l#GQh6+V5^5UTzc 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

0}6dYoQUOeqk9R9j@UE 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 z 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 - -#include "lua.h" - -#include "lualib.h" -#include "lauxlib.h" - - -/* -** these libs are loaded by lua.c and are readily available to any Lua -** program -*/ -static const luaL_Reg loadedlibs[] = { - {LUA_GNAME, luaopen_base}, - {LUA_LOADLIBNAME, luaopen_package}, - {LUA_COLIBNAME, luaopen_coroutine}, - {LUA_TABLIBNAME, luaopen_table}, - {LUA_IOLIBNAME, luaopen_io}, - {LUA_OSLIBNAME, luaopen_os}, - {LUA_STRLIBNAME, luaopen_string}, - {LUA_MATHLIBNAME, luaopen_math}, - {LUA_UTF8LIBNAME, luaopen_utf8}, - {LUA_DBLIBNAME, luaopen_debug}, - {NULL, NULL} -}; - - -LUALIB_API void luaL_openlibs (lua_State *L) { - const luaL_Reg *lib; - /* "require" functions from 'loadedlibs' and set results to global table */ - for (lib = loadedlibs; lib->func; lib++) { - luaL_requiref(L, lib->name, lib->func, 1); - lua_pop(L, 1); /* remove lib */ - } -} - diff --git a/source/external/lua/liolib.c b/source/external/lua/liolib.c deleted file mode 100644 index b08397d..0000000 --- a/source/external/lua/liolib.c +++ /dev/null @@ -1,828 +0,0 @@ -/* -** $Id: liolib.c $ -** Standard I/O (and system) library -** See Copyright Notice in lua.h -*/ - -#define liolib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - - - -/* -** Change this macro to accept other modes for 'fopen' besides -** the standard ones. -*/ -#if !defined(l_checkmode) - -/* accepted extensions to 'mode' in 'fopen' */ -#if !defined(L_MODEEXT) -#define L_MODEEXT "b" -#endif - -/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */ -static int l_checkmode (const char *mode) { - return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && - (*mode != '+' || ((void)(++mode), 1)) && /* skip if char is '+' */ - (strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */ -} - -#endif - -/* -** {====================================================== -** l_popen spawns a new process connected to the current -** one through the file streams. -** ======================================================= -*/ - -#if !defined(l_popen) /* { */ - -#if defined(LUA_USE_POSIX) /* { */ - -#define l_popen(L,c,m) (fflush(NULL), popen(c,m)) -#define l_pclose(L,file) (pclose(file)) - -#elif defined(LUA_USE_WINDOWS) /* }{ */ - -#define l_popen(L,c,m) (_popen(c,m)) -#define l_pclose(L,file) (_pclose(file)) - -#if !defined(l_checkmodep) -/* Windows accepts "[rw][bt]?" as valid modes */ -#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && \ - (m[1] == '\0' || ((m[1] == 'b' || m[1] == 't') && m[2] == '\0'))) -#endif - -#else /* }{ */ - -/* ISO C definitions */ -#define l_popen(L,c,m) \ - ((void)c, (void)m, \ - luaL_error(L, "'popen' not supported"), \ - (FILE*)0) -#define l_pclose(L,file) ((void)L, (void)file, -1) - -#endif /* } */ - -#endif /* } */ - - -#if !defined(l_checkmodep) -/* By default, Lua accepts only "r" or "w" as valid modes */ -#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0') -#endif - -/* }====================================================== */ - - -#if !defined(l_getc) /* { */ - -#if defined(LUA_USE_POSIX) -#define l_getc(f) getc_unlocked(f) -#define l_lockfile(f) flockfile(f) -#define l_unlockfile(f) funlockfile(f) -#else -#define l_getc(f) getc(f) -#define l_lockfile(f) ((void)0) -#define l_unlockfile(f) ((void)0) -#endif - -#endif /* } */ - - -/* -** {====================================================== -** l_fseek: configuration for longer offsets -** ======================================================= -*/ - -#if !defined(l_fseek) /* { */ - -#if defined(LUA_USE_POSIX) /* { */ - -#include - -#define l_fseek(f,o,w) fseeko(f,o,w) -#define l_ftell(f) ftello(f) -#define l_seeknum off_t - -#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \ - && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ - -/* Windows (but not DDK) and Visual C++ 2005 or higher */ -#define l_fseek(f,o,w) _fseeki64(f,o,w) -#define l_ftell(f) _ftelli64(f) -#define l_seeknum __int64 - -#else /* }{ */ - -/* ISO C definitions */ -#define l_fseek(f,o,w) fseek(f,o,w) -#define l_ftell(f) ftell(f) -#define l_seeknum long - -#endif /* } */ - -#endif /* } */ - -/* }====================================================== */ - - - -#define IO_PREFIX "_IO_" -#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1) -#define IO_INPUT (IO_PREFIX "input") -#define IO_OUTPUT (IO_PREFIX "output") - - -typedef luaL_Stream LStream; - - -#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) - -#define isclosed(p) ((p)->closef == NULL) - - -static int io_type (lua_State *L) { - LStream *p; - luaL_checkany(L, 1); - p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); - if (p == NULL) - luaL_pushfail(L); /* not a file */ - else if (isclosed(p)) - lua_pushliteral(L, "closed file"); - else - lua_pushliteral(L, "file"); - return 1; -} - - -static int f_tostring (lua_State *L) { - LStream *p = tolstream(L); - if (isclosed(p)) - lua_pushliteral(L, "file (closed)"); - else - lua_pushfstring(L, "file (%p)", p->f); - return 1; -} - - -static FILE *tofile (lua_State *L) { - LStream *p = tolstream(L); - if (l_unlikely(isclosed(p))) - luaL_error(L, "attempt to use a closed file"); - lua_assert(p->f); - return p->f; -} - - -/* -** When creating file handles, always creates a 'closed' file handle -** before opening the actual file; so, if there is a memory error, the -** handle is in a consistent state. -*/ -static LStream *newprefile (lua_State *L) { - LStream *p = (LStream *)lua_newuserdatauv(L, sizeof(LStream), 0); - p->closef = NULL; /* mark file handle as 'closed' */ - luaL_setmetatable(L, LUA_FILEHANDLE); - return p; -} - - -/* -** Calls the 'close' function from a file handle. The 'volatile' avoids -** a bug in some versions of the Clang compiler (e.g., clang 3.0 for -** 32 bits). -*/ -static int aux_close (lua_State *L) { - LStream *p = tolstream(L); - volatile lua_CFunction cf = p->closef; - p->closef = NULL; /* mark stream as closed */ - return (*cf)(L); /* close it */ -} - - -static int f_close (lua_State *L) { - tofile(L); /* make sure argument is an open stream */ - return aux_close(L); -} - - -static int io_close (lua_State *L) { - if (lua_isnone(L, 1)) /* no argument? */ - lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use default output */ - return f_close(L); -} - - -static int f_gc (lua_State *L) { - LStream *p = tolstream(L); - if (!isclosed(p) && p->f != NULL) - aux_close(L); /* ignore closed and incompletely open files */ - return 0; -} - - -/* -** function to close regular files -*/ -static int io_fclose (lua_State *L) { - LStream *p = tolstream(L); - int res = fclose(p->f); - return luaL_fileresult(L, (res == 0), NULL); -} - - -static LStream *newfile (lua_State *L) { - LStream *p = newprefile(L); - p->f = NULL; - p->closef = &io_fclose; - return p; -} - - -static void opencheck (lua_State *L, const char *fname, const char *mode) { - LStream *p = newfile(L); - p->f = fopen(fname, mode); - if (l_unlikely(p->f == NULL)) - luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno)); -} - - -static int io_open (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - LStream *p = newfile(L); - const char *md = mode; /* to traverse/check mode */ - luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); - p->f = fopen(filename, mode); - return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; -} - - -/* -** function to close 'popen' files -*/ -static int io_pclose (lua_State *L) { - LStream *p = tolstream(L); - errno = 0; - return luaL_execresult(L, l_pclose(L, p->f)); -} - - -static int io_popen (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - LStream *p = newprefile(L); - luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode"); - p->f = l_popen(L, filename, mode); - p->closef = &io_pclose; - return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; -} - - -static int io_tmpfile (lua_State *L) { - LStream *p = newfile(L); - p->f = tmpfile(); - return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; -} - - -static FILE *getiofile (lua_State *L, const char *findex) { - LStream *p; - lua_getfield(L, LUA_REGISTRYINDEX, findex); - p = (LStream *)lua_touserdata(L, -1); - if (l_unlikely(isclosed(p))) - luaL_error(L, "default %s file is closed", findex + IOPREF_LEN); - return p->f; -} - - -static int g_iofile (lua_State *L, const char *f, const char *mode) { - if (!lua_isnoneornil(L, 1)) { - const char *filename = lua_tostring(L, 1); - if (filename) - opencheck(L, filename, mode); - else { - tofile(L); /* check that it's a valid file handle */ - lua_pushvalue(L, 1); - } - lua_setfield(L, LUA_REGISTRYINDEX, f); - } - /* return current value */ - lua_getfield(L, LUA_REGISTRYINDEX, f); - return 1; -} - - -static int io_input (lua_State *L) { - return g_iofile(L, IO_INPUT, "r"); -} - - -static int io_output (lua_State *L) { - return g_iofile(L, IO_OUTPUT, "w"); -} - - -static int io_readline (lua_State *L); - - -/* -** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit -** in the limit for upvalues of a closure) -*/ -#define MAXARGLINE 250 - -/* -** Auxiliary function to create the iteration function for 'lines'. -** The iteration function is a closure over 'io_readline', with -** the following upvalues: -** 1) The file being read (first value in the stack) -** 2) the number of arguments to read -** 3) a boolean, true iff file has to be closed when finished ('toclose') -** *) a variable number of format arguments (rest of the stack) -*/ -static void aux_lines (lua_State *L, int toclose) { - int n = lua_gettop(L) - 1; /* number of arguments to read */ - luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments"); - lua_pushvalue(L, 1); /* file */ - lua_pushinteger(L, n); /* number of arguments to read */ - lua_pushboolean(L, toclose); /* close/not close file when finished */ - lua_rotate(L, 2, 3); /* move the three values to their positions */ - lua_pushcclosure(L, io_readline, 3 + n); -} - - -static int f_lines (lua_State *L) { - tofile(L); /* check that it's a valid file handle */ - aux_lines(L, 0); - return 1; -} - - -/* -** Return an iteration function for 'io.lines'. If file has to be -** closed, also returns the file itself as a second result (to be -** closed as the state at the exit of a generic for). -*/ -static int io_lines (lua_State *L) { - int toclose; - if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ - if (lua_isnil(L, 1)) { /* no file name? */ - lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ - lua_replace(L, 1); /* put it at index 1 */ - tofile(L); /* check that it's a valid file handle */ - toclose = 0; /* do not close it after iteration */ - } - else { /* open a new file */ - const char *filename = luaL_checkstring(L, 1); - opencheck(L, filename, "r"); - lua_replace(L, 1); /* put file at index 1 */ - toclose = 1; /* close it after iteration */ - } - aux_lines(L, toclose); /* push iteration function */ - if (toclose) { - lua_pushnil(L); /* state */ - lua_pushnil(L); /* control */ - lua_pushvalue(L, 1); /* file is the to-be-closed variable (4th result) */ - return 4; - } - else - return 1; -} - - -/* -** {====================================================== -** READ -** ======================================================= -*/ - - -/* maximum length of a numeral */ -#if !defined (L_MAXLENNUM) -#define L_MAXLENNUM 200 -#endif - - -/* auxiliary structure used by 'read_number' */ -typedef struct { - FILE *f; /* file being read */ - int c; /* current character (look ahead) */ - int n; /* number of elements in buffer 'buff' */ - char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */ -} RN; - - -/* -** Add current char to buffer (if not out of space) and read next one -*/ -static int nextc (RN *rn) { - if (l_unlikely(rn->n >= L_MAXLENNUM)) { /* buffer overflow? */ - rn->buff[0] = '\0'; /* invalidate result */ - return 0; /* fail */ - } - else { - rn->buff[rn->n++] = rn->c; /* save current char */ - rn->c = l_getc(rn->f); /* read next one */ - return 1; - } -} - - -/* -** Accept current char if it is in 'set' (of size 2) -*/ -static int test2 (RN *rn, const char *set) { - if (rn->c == set[0] || rn->c == set[1]) - return nextc(rn); - else return 0; -} - - -/* -** Read a sequence of (hex)digits -*/ -static int readdigits (RN *rn, int hex) { - int count = 0; - while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn)) - count++; - return count; -} - - -/* -** 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 -** correct and to convert it to a Lua number. -*/ -static int read_number (lua_State *L, FILE *f) { - RN rn; - int count = 0; - int hex = 0; - char decp[2]; - rn.f = f; rn.n = 0; - decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */ - decp[1] = '.'; /* always accept a dot */ - l_lockfile(rn.f); - do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */ - test2(&rn, "-+"); /* optional sign */ - if (test2(&rn, "00")) { - if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */ - else count = 1; /* count initial '0' as a valid digit */ - } - count += readdigits(&rn, hex); /* integral part */ - if (test2(&rn, decp)) /* decimal point? */ - count += readdigits(&rn, hex); /* fractional part */ - if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */ - test2(&rn, "-+"); /* exponent sign */ - readdigits(&rn, 0); /* exponent digits */ - } - ungetc(rn.c, rn.f); /* unread look-ahead char */ - l_unlockfile(rn.f); - rn.buff[rn.n] = '\0'; /* finish string */ - if (l_likely(lua_stringtonumber(L, rn.buff))) - return 1; /* ok, it is a valid number */ - else { /* invalid format */ - lua_pushnil(L); /* "result" to be removed */ - return 0; /* read fails */ - } -} - - -static int test_eof (lua_State *L, FILE *f) { - int c = getc(f); - ungetc(c, f); /* no-op when c == EOF */ - lua_pushliteral(L, ""); - return (c != EOF); -} - - -static int read_line (lua_State *L, FILE *f, int chop) { - luaL_Buffer b; - int c; - luaL_buffinit(L, &b); - do { /* may need to read several chunks to get whole line */ - char *buff = luaL_prepbuffer(&b); /* preallocate buffer space */ - int i = 0; - l_lockfile(f); /* no memory errors can happen inside the lock */ - while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') - buff[i++] = c; /* read up to end of line or buffer limit */ - l_unlockfile(f); - luaL_addsize(&b, i); - } while (c != EOF && c != '\n'); /* repeat until end of line */ - if (!chop && c == '\n') /* want a newline and have one? */ - luaL_addchar(&b, c); /* add ending newline to result */ - luaL_pushresult(&b); /* close buffer */ - /* return ok if read something (either a newline or something else) */ - return (c == '\n' || lua_rawlen(L, -1) > 0); -} - - -static void read_all (lua_State *L, FILE *f) { - size_t nr; - luaL_Buffer b; - luaL_buffinit(L, &b); - do { /* read file in chunks of LUAL_BUFFERSIZE bytes */ - char *p = luaL_prepbuffer(&b); - nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f); - luaL_addsize(&b, nr); - } while (nr == LUAL_BUFFERSIZE); - luaL_pushresult(&b); /* close buffer */ -} - - -static int read_chars (lua_State *L, FILE *f, size_t n) { - size_t nr; /* number of chars actually read */ - char *p; - luaL_Buffer b; - luaL_buffinit(L, &b); - p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ - nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ - luaL_addsize(&b, nr); - luaL_pushresult(&b); /* close buffer */ - return (nr > 0); /* true iff read something */ -} - - -static int g_read (lua_State *L, FILE *f, int first) { - int nargs = lua_gettop(L) - 1; - int n, success; - clearerr(f); - if (nargs == 0) { /* no arguments? */ - success = read_line(L, f, 1); - n = first + 1; /* to return 1 result */ - } - else { - /* ensure stack space for all results and for auxlib's buffer */ - luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); - success = 1; - for (n = first; nargs-- && success; n++) { - if (lua_type(L, n) == LUA_TNUMBER) { - size_t l = (size_t)luaL_checkinteger(L, n); - success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); - } - else { - const char *p = luaL_checkstring(L, n); - if (*p == '*') p++; /* skip optional '*' (for compatibility) */ - switch (*p) { - case 'n': /* number */ - success = read_number(L, f); - break; - case 'l': /* line */ - success = read_line(L, f, 1); - break; - case 'L': /* line with end-of-line */ - success = read_line(L, f, 0); - break; - case 'a': /* file */ - read_all(L, f); /* read entire file */ - success = 1; /* always success */ - break; - default: - return luaL_argerror(L, n, "invalid format"); - } - } - } - } - if (ferror(f)) - return luaL_fileresult(L, 0, NULL); - if (!success) { - lua_pop(L, 1); /* remove last result */ - luaL_pushfail(L); /* push nil instead */ - } - return n - first; -} - - -static int io_read (lua_State *L) { - return g_read(L, getiofile(L, IO_INPUT), 1); -} - - -static int f_read (lua_State *L) { - return g_read(L, tofile(L), 2); -} - - -/* -** Iteration function for 'lines'. -*/ -static int io_readline (lua_State *L) { - LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); - int i; - int n = (int)lua_tointeger(L, lua_upvalueindex(2)); - if (isclosed(p)) /* file is already closed? */ - return luaL_error(L, "file is already closed"); - lua_settop(L , 1); - luaL_checkstack(L, n, "too many arguments"); - for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ - lua_pushvalue(L, lua_upvalueindex(3 + i)); - n = g_read(L, p->f, 2); /* 'n' is number of results */ - lua_assert(n > 0); /* should return at least a nil */ - if (lua_toboolean(L, -n)) /* read at least one value? */ - return n; /* return them */ - else { /* first result is false: EOF or error */ - if (n > 1) { /* is there error information? */ - /* 2nd result is error message */ - return luaL_error(L, "%s", lua_tostring(L, -n + 1)); - } - if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ - lua_settop(L, 0); /* clear stack */ - lua_pushvalue(L, lua_upvalueindex(1)); /* push file at index 1 */ - aux_close(L); /* close it */ - } - return 0; - } -} - -/* }====================================================== */ - - -static int g_write (lua_State *L, FILE *f, int arg) { - int nargs = lua_gettop(L) - arg; - int status = 1; - for (; nargs--; arg++) { - if (lua_type(L, arg) == LUA_TNUMBER) { - /* optimization: could be done exactly as for strings */ - int len = lua_isinteger(L, arg) - ? fprintf(f, LUA_INTEGER_FMT, - (LUAI_UACINT)lua_tointeger(L, arg)) - : fprintf(f, LUA_NUMBER_FMT, - (LUAI_UACNUMBER)lua_tonumber(L, arg)); - status = status && (len > 0); - } - else { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - status = status && (fwrite(s, sizeof(char), l, f) == l); - } - } - if (l_likely(status)) - return 1; /* file handle already on stack top */ - else return luaL_fileresult(L, status, NULL); -} - - -static int io_write (lua_State *L) { - return g_write(L, getiofile(L, IO_OUTPUT), 1); -} - - -static int f_write (lua_State *L) { - FILE *f = tofile(L); - lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ - return g_write(L, f, 2); -} - - -static int f_seek (lua_State *L) { - static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; - static const char *const modenames[] = {"set", "cur", "end", NULL}; - FILE *f = tofile(L); - int op = luaL_checkoption(L, 2, "cur", modenames); - lua_Integer p3 = luaL_optinteger(L, 3, 0); - l_seeknum offset = (l_seeknum)p3; - luaL_argcheck(L, (lua_Integer)offset == p3, 3, - "not an integer in proper range"); - op = l_fseek(f, offset, mode[op]); - if (l_unlikely(op)) - return luaL_fileresult(L, 0, NULL); /* error */ - else { - lua_pushinteger(L, (lua_Integer)l_ftell(f)); - return 1; - } -} - - -static int f_setvbuf (lua_State *L) { - static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; - static const char *const modenames[] = {"no", "full", "line", NULL}; - FILE *f = tofile(L); - int op = luaL_checkoption(L, 2, NULL, modenames); - lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); - int res = setvbuf(f, NULL, mode[op], (size_t)sz); - return luaL_fileresult(L, res == 0, NULL); -} - - - -static int io_flush (lua_State *L) { - return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); -} - - -static int f_flush (lua_State *L) { - return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); -} - - -/* -** functions for 'io' library -*/ -static const luaL_Reg iolib[] = { - {"close", io_close}, - {"flush", io_flush}, - {"input", io_input}, - {"lines", io_lines}, - {"open", io_open}, - {"output", io_output}, - {"popen", io_popen}, - {"read", io_read}, - {"tmpfile", io_tmpfile}, - {"type", io_type}, - {"write", io_write}, - {NULL, NULL} -}; - - -/* -** methods for file handles -*/ -static const luaL_Reg meth[] = { - {"read", f_read}, - {"write", f_write}, - {"lines", f_lines}, - {"flush", f_flush}, - {"seek", f_seek}, - {"close", f_close}, - {"setvbuf", f_setvbuf}, - {NULL, NULL} -}; - - -/* -** metamethods for file handles -*/ -static const luaL_Reg metameth[] = { - {"__index", NULL}, /* place holder */ - {"__gc", f_gc}, - {"__close", f_gc}, - {"__tostring", f_tostring}, - {NULL, NULL} -}; - - -static void createmeta (lua_State *L) { - luaL_newmetatable(L, LUA_FILEHANDLE); /* metatable for file handles */ - luaL_setfuncs(L, metameth, 0); /* add metamethods to new metatable */ - luaL_newlibtable(L, meth); /* create method table */ - luaL_setfuncs(L, meth, 0); /* add file methods to method table */ - lua_setfield(L, -2, "__index"); /* metatable.__index = method table */ - lua_pop(L, 1); /* pop metatable */ -} - - -/* -** function to (not) close the standard files stdin, stdout, and stderr -*/ -static int io_noclose (lua_State *L) { - LStream *p = tolstream(L); - p->closef = &io_noclose; /* keep file opened */ - luaL_pushfail(L); - lua_pushliteral(L, "cannot close standard file"); - return 2; -} - - -static void createstdfile (lua_State *L, FILE *f, const char *k, - const char *fname) { - LStream *p = newprefile(L); - p->f = f; - p->closef = &io_noclose; - if (k != NULL) { - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ - } - lua_setfield(L, -2, fname); /* add file to module */ -} - - -LUAMOD_API int luaopen_io (lua_State *L) { - luaL_newlib(L, iolib); /* new module */ - createmeta(L); - /* create (and set) default files */ - createstdfile(L, stdin, IO_INPUT, "stdin"); - createstdfile(L, stdout, IO_OUTPUT, "stdout"); - createstdfile(L, stderr, NULL, "stderr"); - return 1; -} - diff --git a/source/external/lua/ljumptab.h b/source/external/lua/ljumptab.h index 8306f25..52fa6d7 100644 --- a/source/external/lua/ljumptab.h +++ b/source/external/lua/ljumptab.h @@ -21,7 +21,7 @@ static const void *const disptab[NUM_OPCODES] = { #if 0 ** you can update the following list with this command: ** -** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h +** sed -n '/^OP_/!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h ** #endif @@ -57,8 +57,8 @@ static const void *const disptab[NUM_OPCODES] = { &&L_OP_BANDK, &&L_OP_BORK, &&L_OP_BXORK, -&&L_OP_SHRI, &&L_OP_SHLI, +&&L_OP_SHRI, &&L_OP_ADD, &&L_OP_SUB, &&L_OP_MUL, @@ -106,6 +106,8 @@ static const void *const disptab[NUM_OPCODES] = { &&L_OP_SETLIST, &&L_OP_CLOSURE, &&L_OP_VARARG, +&&L_OP_GETVARG, +&&L_OP_ERRNNIL, &&L_OP_VARARGPREP, &&L_OP_EXTRAARG diff --git a/source/external/lua/llex.c b/source/external/lua/llex.c deleted file mode 100644 index e991517..0000000 --- a/source/external/lua/llex.c +++ /dev/null @@ -1,581 +0,0 @@ -/* -** $Id: llex.c $ -** Lexical Analyzer -** See Copyright Notice in lua.h -*/ - -#define llex_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include - -#include "lua.h" - -#include "lctype.h" -#include "ldebug.h" -#include "ldo.h" -#include "lgc.h" -#include "llex.h" -#include "lobject.h" -#include "lparser.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "lzio.h" - - - -#define next(ls) (ls->current = zgetc(ls->z)) - - - -#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') - - -/* ORDER RESERVED */ -static const char *const luaX_tokens [] = { - "and", "break", "do", "else", "elseif", - "end", "false", "for", "function", "goto", "if", - "in", "local", "nil", "not", "or", "repeat", - "return", "then", "true", "until", "while", - "//", "..", "...", "==", ">=", "<=", "~=", - "<<", ">>", "::", "", - "", "", "", "" -}; - - -#define save_and_next(ls) (save(ls, ls->current), next(ls)) - - -static l_noret lexerror (LexState *ls, const char *msg, int token); - - -static void save (LexState *ls, int c) { - Mbuffer *b = ls->buff; - if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { - size_t newsize; - if (luaZ_sizebuffer(b) >= MAX_SIZE/2) - lexerror(ls, "lexical element too long", 0); - newsize = luaZ_sizebuffer(b) * 2; - luaZ_resizebuffer(ls->L, b, newsize); - } - b->buffer[luaZ_bufflen(b)++] = cast_char(c); -} - - -void luaX_init (lua_State *L) { - int i; - TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */ - luaC_fix(L, obj2gco(e)); /* never collect this name */ - for (i=0; iextra = cast_byte(i+1); /* reserved word */ - } -} - - -const char *luaX_token2str (LexState *ls, int token) { - if (token < FIRST_RESERVED) { /* single-byte symbols? */ - if (lisprint(token)) - return luaO_pushfstring(ls->L, "'%c'", token); - else /* control character */ - return luaO_pushfstring(ls->L, "'<\\%d>'", token); - } - else { - const char *s = luaX_tokens[token - FIRST_RESERVED]; - if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ - return luaO_pushfstring(ls->L, "'%s'", s); - else /* names, strings, and numerals */ - return s; - } -} - - -static const char *txtToken (LexState *ls, int token) { - switch (token) { - case TK_NAME: case TK_STRING: - case TK_FLT: case TK_INT: - save(ls, '\0'); - return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff)); - default: - return luaX_token2str(ls, token); - } -} - - -static l_noret lexerror (LexState *ls, const char *msg, int token) { - 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); -} - - -l_noret luaX_syntaxerror (LexState *ls, const char *msg) { - lexerror(ls, msg, ls->t.token); -} - - -/* -** Creates a new string and anchors it in scanner's table so that it -** will not be collected until the end of the compilation; by that time -** it should be anchored somewhere. It also internalizes long strings, -** ensuring there is only one copy of each unique string. The table -** here is used as a set: the string enters as the key, while its value -** is irrelevant. We use the string itself as the value only because it -** is a TValue readly available. Later, the code generation can change -** this value. -*/ -TString *luaX_newstring (LexState *ls, const char *str, size_t l) { - lua_State *L = ls->L; - TString *ts = luaS_newlstr(L, str, l); /* create new string */ - const TValue *o = luaH_getstr(ls->h, ts); - if (!ttisnil(o)) /* string already present? */ - ts = keystrval(nodefromval(o)); /* get saved copy */ - else { /* not in use yet */ - TValue *stv = s2v(L->top++); /* reserve stack space for string */ - setsvalue(L, stv, ts); /* temporarily anchor the string */ - luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */ - /* table is not a metatable, so it does not need to invalidate cache */ - luaC_checkGC(L); - L->top--; /* remove string from stack */ - } - return ts; -} - - -/* -** increment line number and skips newline sequence (any of -** \n, \r, \n\r, or \r\n) -*/ -static void inclinenumber (LexState *ls) { - int old = ls->current; - lua_assert(currIsNewline(ls)); - next(ls); /* skip '\n' or '\r' */ - if (currIsNewline(ls) && ls->current != old) - next(ls); /* skip '\n\r' or '\r\n' */ - if (++ls->linenumber >= MAX_INT) - lexerror(ls, "chunk has too many lines", 0); -} - - -void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, - int firstchar) { - ls->t.token = 0; - ls->L = L; - ls->current = firstchar; - ls->lookahead.token = TK_EOS; /* no look-ahead token */ - ls->z = z; - ls->fs = NULL; - ls->linenumber = 1; - ls->lastline = 1; - ls->source = source; - ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */ - luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ -} - - - -/* -** ======================================================= -** LEXICAL ANALYZER -** ======================================================= -*/ - - -static int check_next1 (LexState *ls, int c) { - if (ls->current == c) { - next(ls); - return 1; - } - else return 0; -} - - -/* -** Check whether current char is in set 'set' (with two chars) and -** saves it -*/ -static int check_next2 (LexState *ls, const char *set) { - lua_assert(set[2] == '\0'); - if (ls->current == set[0] || ls->current == set[1]) { - save_and_next(ls); - return 1; - } - else return 0; -} - - -/* LUA_NUMBER */ -/* -** This function is quite liberal in what it accepts, as 'luaO_str2num' -** will reject ill-formed numerals. Roughly, it accepts the following -** pattern: -** -** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))* -** -** The only tricky part is to accept [+-] only after a valid exponent -** mark, to avoid reading '3-4' or '0xe+1' as a single number. -** -** The caller might have already read an initial dot. -*/ -static int read_numeral (LexState *ls, SemInfo *seminfo) { - TValue obj; - const char *expo = "Ee"; - int first = ls->current; - lua_assert(lisdigit(ls->current)); - save_and_next(ls); - if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */ - expo = "Pp"; - for (;;) { - if (check_next2(ls, expo)) /* exponent mark? */ - check_next2(ls, "-+"); /* optional exponent sign */ - else if (lisxdigit(ls->current) || ls->current == '.') /* '%x|%.' */ - save_and_next(ls); - else break; - } - if (lislalpha(ls->current)) /* is numeral touching a letter? */ - save_and_next(ls); /* force an error */ - save(ls, '\0'); - if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */ - lexerror(ls, "malformed number", TK_FLT); - if (ttisinteger(&obj)) { - seminfo->i = ivalue(&obj); - return TK_INT; - } - else { - lua_assert(ttisfloat(&obj)); - seminfo->r = fltvalue(&obj); - return TK_FLT; - } -} - - -/* -** read a sequence '[=*[' or ']=*]', leaving the last bracket. If -** sequence is well formed, return its number of '='s + 2; otherwise, -** return 1 if it is a single bracket (no '='s and no 2nd bracket); -** otherwise (an unfinished '[==...') return 0. -*/ -static size_t skip_sep (LexState *ls) { - size_t count = 0; - int s = ls->current; - lua_assert(s == '[' || s == ']'); - save_and_next(ls); - while (ls->current == '=') { - save_and_next(ls); - count++; - } - return (ls->current == s) ? count + 2 - : (count == 0) ? 1 - : 0; -} - - -static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { - int line = ls->linenumber; /* initial line (for error message) */ - save_and_next(ls); /* skip 2nd '[' */ - if (currIsNewline(ls)) /* string starts with a newline? */ - inclinenumber(ls); /* skip it */ - for (;;) { - switch (ls->current) { - case EOZ: { /* error */ - const char *what = (seminfo ? "string" : "comment"); - const char *msg = luaO_pushfstring(ls->L, - "unfinished long %s (starting at line %d)", what, line); - lexerror(ls, msg, TK_EOS); - break; /* to avoid warnings */ - } - case ']': { - if (skip_sep(ls) == sep) { - save_and_next(ls); /* skip 2nd ']' */ - goto endloop; - } - break; - } - case '\n': case '\r': { - save(ls, '\n'); - inclinenumber(ls); - if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ - break; - } - default: { - if (seminfo) save_and_next(ls); - else next(ls); - } - } - } endloop: - if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + sep, - luaZ_bufflen(ls->buff) - 2 * sep); -} - - -static void esccheck (LexState *ls, int c, const char *msg) { - if (!c) { - if (ls->current != EOZ) - save_and_next(ls); /* add current to buffer for error message */ - lexerror(ls, msg, TK_STRING); - } -} - - -static int gethexa (LexState *ls) { - save_and_next(ls); - esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected"); - return luaO_hexavalue(ls->current); -} - - -static int readhexaesc (LexState *ls) { - int r = gethexa(ls); - r = (r << 4) + gethexa(ls); - luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */ - return r; -} - - -static unsigned long readutf8esc (LexState *ls) { - unsigned long r; - int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ - save_and_next(ls); /* skip 'u' */ - esccheck(ls, ls->current == '{', "missing '{'"); - r = gethexa(ls); /* must have at least one digit */ - while (cast_void(save_and_next(ls)), lisxdigit(ls->current)) { - i++; - esccheck(ls, r <= (0x7FFFFFFFu >> 4), "UTF-8 value too large"); - r = (r << 4) + luaO_hexavalue(ls->current); - } - esccheck(ls, ls->current == '}', "missing '}'"); - next(ls); /* skip '}' */ - luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */ - return r; -} - - -static void utf8esc (LexState *ls) { - char buff[UTF8BUFFSZ]; - int n = luaO_utf8esc(buff, readutf8esc(ls)); - for (; n > 0; n--) /* add 'buff' to string */ - save(ls, buff[UTF8BUFFSZ - n]); -} - - -static int readdecesc (LexState *ls) { - int i; - int r = 0; /* result accumulator */ - for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ - r = 10*r + ls->current - '0'; - save_and_next(ls); - } - esccheck(ls, r <= UCHAR_MAX, "decimal escape too large"); - luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */ - return r; -} - - -static void read_string (LexState *ls, int del, SemInfo *seminfo) { - save_and_next(ls); /* keep delimiter (for error messages) */ - while (ls->current != del) { - switch (ls->current) { - case EOZ: - lexerror(ls, "unfinished string", TK_EOS); - break; /* to avoid warnings */ - case '\n': - case '\r': - lexerror(ls, "unfinished string", TK_STRING); - break; /* to avoid warnings */ - case '\\': { /* escape sequences */ - int c; /* final character to be saved */ - save_and_next(ls); /* keep '\\' for error messages */ - switch (ls->current) { - case 'a': c = '\a'; goto read_save; - case 'b': c = '\b'; goto read_save; - case 'f': c = '\f'; goto read_save; - case 'n': c = '\n'; goto read_save; - case 'r': c = '\r'; goto read_save; - case 't': c = '\t'; goto read_save; - case 'v': c = '\v'; goto read_save; - case 'x': c = readhexaesc(ls); goto read_save; - case 'u': utf8esc(ls); goto no_save; - case '\n': case '\r': - inclinenumber(ls); c = '\n'; goto only_save; - case '\\': case '\"': case '\'': - c = ls->current; goto read_save; - case EOZ: goto no_save; /* will raise an error next loop */ - case 'z': { /* zap following span of spaces */ - luaZ_buffremove(ls->buff, 1); /* remove '\\' */ - next(ls); /* skip the 'z' */ - while (lisspace(ls->current)) { - if (currIsNewline(ls)) inclinenumber(ls); - else next(ls); - } - goto no_save; - } - default: { - esccheck(ls, lisdigit(ls->current), "invalid escape sequence"); - c = readdecesc(ls); /* digital escape '\ddd' */ - goto only_save; - } - } - read_save: - next(ls); - /* go through */ - only_save: - luaZ_buffremove(ls->buff, 1); /* remove '\\' */ - save(ls, c); - /* go through */ - no_save: break; - } - default: - save_and_next(ls); - } - } - save_and_next(ls); /* skip delimiter */ - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, - luaZ_bufflen(ls->buff) - 2); -} - - -static int llex (LexState *ls, SemInfo *seminfo) { - luaZ_resetbuffer(ls->buff); - for (;;) { - switch (ls->current) { - case '\n': case '\r': { /* line breaks */ - inclinenumber(ls); - break; - } - case ' ': case '\f': case '\t': case '\v': { /* spaces */ - next(ls); - break; - } - case '-': { /* '-' or '--' (comment) */ - next(ls); - if (ls->current != '-') return '-'; - /* else is a comment */ - next(ls); - if (ls->current == '[') { /* long comment? */ - size_t sep = skip_sep(ls); - luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */ - if (sep >= 2) { - read_long_string(ls, NULL, sep); /* skip long comment */ - luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ - break; - } - } - /* else short comment */ - while (!currIsNewline(ls) && ls->current != EOZ) - next(ls); /* skip until end of line (or end of file) */ - break; - } - case '[': { /* long string or simply '[' */ - size_t sep = skip_sep(ls); - if (sep >= 2) { - read_long_string(ls, seminfo, sep); - return TK_STRING; - } - else if (sep == 0) /* '[=...' missing second bracket? */ - lexerror(ls, "invalid long string delimiter", TK_STRING); - return '['; - } - case '=': { - next(ls); - if (check_next1(ls, '=')) return TK_EQ; /* '==' */ - else return '='; - } - case '<': { - next(ls); - if (check_next1(ls, '=')) return TK_LE; /* '<=' */ - else if (check_next1(ls, '<')) return TK_SHL; /* '<<' */ - else return '<'; - } - case '>': { - next(ls); - if (check_next1(ls, '=')) return TK_GE; /* '>=' */ - else if (check_next1(ls, '>')) return TK_SHR; /* '>>' */ - else return '>'; - } - case '/': { - next(ls); - if (check_next1(ls, '/')) return TK_IDIV; /* '//' */ - else return '/'; - } - case '~': { - next(ls); - if (check_next1(ls, '=')) return TK_NE; /* '~=' */ - else return '~'; - } - case ':': { - next(ls); - if (check_next1(ls, ':')) return TK_DBCOLON; /* '::' */ - else return ':'; - } - case '"': case '\'': { /* short literal strings */ - read_string(ls, ls->current, seminfo); - return TK_STRING; - } - case '.': { /* '.', '..', '...', or number */ - save_and_next(ls); - if (check_next1(ls, '.')) { - if (check_next1(ls, '.')) - return TK_DOTS; /* '...' */ - else return TK_CONCAT; /* '..' */ - } - else if (!lisdigit(ls->current)) return '.'; - else return read_numeral(ls, seminfo); - } - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - return read_numeral(ls, seminfo); - } - case EOZ: { - return TK_EOS; - } - default: { - if (lislalpha(ls->current)) { /* identifier or reserved word? */ - TString *ts; - do { - save_and_next(ls); - } while (lislalnum(ls->current)); - ts = luaX_newstring(ls, luaZ_buffer(ls->buff), - luaZ_bufflen(ls->buff)); - seminfo->ts = ts; - if (isreserved(ts)) /* reserved word? */ - return ts->extra - 1 + FIRST_RESERVED; - else { - return TK_NAME; - } - } - else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */ - int c = ls->current; - next(ls); - return c; - } - } - } - } -} - - -void luaX_next (LexState *ls) { - ls->lastline = ls->linenumber; - if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ - ls->t = ls->lookahead; /* use this one */ - ls->lookahead.token = TK_EOS; /* and discharge it */ - } - else - ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ -} - - -int luaX_lookahead (LexState *ls) { - lua_assert(ls->lookahead.token == TK_EOS); - ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); - return ls->lookahead.token; -} - diff --git a/source/external/lua/llex.h b/source/external/lua/llex.h index 389d2f8..37016e8 100644 --- a/source/external/lua/llex.h +++ b/source/external/lua/llex.h @@ -33,8 +33,8 @@ enum RESERVED { /* terminal symbols denoted by reserved words */ TK_AND = FIRST_RESERVED, TK_BREAK, TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, - TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, - TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + TK_GLOBAL, TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, + TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, /* other terminal symbols */ TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_SHL, TK_SHR, @@ -59,7 +59,7 @@ typedef struct Token { } Token; -/* state of the lexer plus state of the parser when shared by all +/* state of the scanner plus state of the parser when shared by all functions */ typedef struct LexState { int current; /* current character (charint) */ @@ -75,6 +75,8 @@ typedef struct LexState { struct Dyndata *dyd; /* dynamic structures used by the parser */ TString *source; /* current source name */ TString *envn; /* environment variable name */ + TString *brkn; /* "break" name (used as a label) */ + TString *glbn; /* "global" name (when not a reserved word) */ } LexState; diff --git a/source/external/lua/llimits.h b/source/external/lua/llimits.h index 025f1c8..fc5cb27 100644 --- a/source/external/lua/llimits.h +++ b/source/external/lua/llimits.h @@ -15,50 +15,49 @@ #include "lua.h" +#define l_numbits(t) cast_int(sizeof(t) * CHAR_BIT) + /* -** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count -** the total memory used by Lua (in bytes). Usually, 'size_t' and +** 'l_mem' is a signed integer big enough to count the total memory +** used by Lua. (It is signed due to the use of debt in several +** computations.) 'lu_mem' is a corresponding unsigned type. Usually, ** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. */ #if defined(LUAI_MEM) /* { external definitions? */ -typedef LUAI_UMEM lu_mem; typedef LUAI_MEM l_mem; +typedef LUAI_UMEM lu_mem; #elif LUAI_IS32INT /* }{ */ -typedef size_t lu_mem; typedef ptrdiff_t l_mem; +typedef size_t lu_mem; #else /* 16-bit ints */ /* }{ */ -typedef unsigned long lu_mem; typedef long l_mem; +typedef unsigned long lu_mem; #endif /* } */ +#define MAX_LMEM \ + cast(l_mem, (cast(lu_mem, 1) << (l_numbits(l_mem) - 1)) - 1) + /* chars used as small naturals (so that 'char' is reserved for characters) */ typedef unsigned char lu_byte; typedef signed char ls_byte; +/* Type for thread status/error codes */ +typedef lu_byte TStatus; + +/* The C API still uses 'int' for status/error codes */ +#define APIstatus(st) cast_int(st) + /* maximum value for size_t */ #define MAX_SIZET ((size_t)(~(size_t)0)) -/* maximum size visible for Lua (must be representable in a lua_Integer) */ -#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ - : (size_t)(LUA_MAXINTEGER)) - - -#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) - -#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) - - -#define MAX_INT INT_MAX /* maximum value of an int */ - - /* -** floor of the log2 of the maximum signed value for integral type 't'. -** (That is, maximum 'n' such that '2^n' fits in the given signed type.) +** Maximum size for strings and userdata visible for Lua; should be +** representable as a lua_Integer and as a size_t. */ -#define log2maxs(t) (sizeof(t) * 8 - 2) - +#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ + : cast_sizet(LUA_MAXINTEGER)) /* ** test whether an unsigned value is a power of 2 (or zero) @@ -71,11 +70,24 @@ typedef signed char ls_byte; /* -** conversion of pointer to unsigned integer: -** this is for hashing only; there is no problem if the integer -** cannot hold the whole pointer value +** conversion of pointer to unsigned integer: this is for hashing only; +** there is no problem if the integer cannot hold the whole pointer +** value. (In strict ISO C this may cause undefined behavior, but no +** actual machine seems to bother.) */ -#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX)) +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(UINTPTR_MAX) /* even in C99 this type is optional */ +#define L_P2I uintptr_t +#else /* no 'intptr'? */ +#define L_P2I uintmax_t /* use the largest available integer */ +#endif +#else /* C89 option */ +#define L_P2I size_t +#endif + +#define point2uint(p) cast_uint((L_P2I)(p) & UINT_MAX) @@ -91,26 +103,18 @@ typedef LUAI_UACINT l_uacInt; #undef NDEBUG #include #define lua_assert(c) assert(c) +#define assert_code(c) c #endif #if defined(lua_assert) -#define check_exp(c,e) (lua_assert(c), (e)) -/* to avoid problems with conditions too long */ -#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) #else #define lua_assert(c) ((void)0) -#define check_exp(c,e) (e) -#define lua_longassert(c) ((void)0) +#define assert_code(c) ((void)0) #endif -/* -** assertion for checking API calls -*/ -#if !defined(luai_apicheck) -#define luai_apicheck(l,e) ((void)l, lua_assert(e)) -#endif - -#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) +#define check_exp(c,e) (lua_assert(c), (e)) +/* to avoid problems with conditions too long */ +#define lua_longassert(c) assert_code((c) ? (void)0 : lua_assert(0)) /* macro to avoid warnings about unused variables */ @@ -126,12 +130,15 @@ typedef LUAI_UACINT l_uacInt; #define cast_voidp(i) cast(void *, (i)) #define cast_num(i) cast(lua_Number, (i)) #define cast_int(i) cast(int, (i)) +#define cast_short(i) cast(short, (i)) #define cast_uint(i) cast(unsigned int, (i)) #define cast_byte(i) cast(lu_byte, (i)) #define cast_uchar(i) cast(unsigned char, (i)) #define cast_char(i) cast(char, (i)) #define cast_charp(i) cast(char *, (i)) #define cast_sizet(i) cast(size_t, (i)) +#define cast_Integer(i) cast(lua_Integer, (i)) +#define cast_Inst(i) cast(Instruction, (i)) /* cast a signed lua_Integer to lua_Unsigned */ @@ -148,6 +155,38 @@ typedef LUAI_UACINT l_uacInt; #define l_castU2S(i) ((lua_Integer)(i)) #endif +/* +** cast a size_t to lua_Integer: These casts are always valid for +** sizes of Lua objects (see MAX_SIZE) +*/ +#define cast_st2S(sz) ((lua_Integer)(sz)) + +/* Cast a ptrdiff_t to size_t, when it is known that the minuend +** comes from the subtrahend (the base) +*/ +#define ct_diff2sz(df) ((size_t)(df)) + +/* ptrdiff_t to lua_Integer */ +#define ct_diff2S(df) cast_st2S(ct_diff2sz(df)) + +/* +** Special type equivalent to '(void*)' for functions (to suppress some +** warnings when converting function pointers) +*/ +typedef void (*voidf)(void); + +/* +** 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__) +#define cast_func(p) (__extension__ (voidf)(p)) +#else +#define cast_func(p) ((voidf)(p)) +#endif + + /* ** non-return type @@ -166,8 +205,21 @@ typedef LUAI_UACINT l_uacInt; /* -** type for virtual-machine instructions; -** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +** Inline functions +*/ +#if !defined(LUA_USE_C89) +#define l_inline inline +#elif defined(__GNUC__) +#define l_inline __inline__ +#else +#define l_inline /* empty */ +#endif + +#define l_sinline static l_inline + + +/* +** An unsigned with (at least) 4 bytes */ #if LUAI_IS32INT typedef unsigned int l_uint32; @@ -175,107 +227,6 @@ typedef unsigned int l_uint32; typedef unsigned long l_uint32; #endif -typedef l_uint32 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 - - -/* -** 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 128 -#endif - - -/* -** Size of cache for strings in the API. 'N' is the number of -** sets (better be a prime) and "M" is the size of each set (M == 1 -** makes a direct cache.) -*/ -#if !defined(STRCACHE_N) -#define STRCACHE_N 53 -#define STRCACHE_M 2 -#endif - - -/* minimum size for string buffer */ -#if !defined(LUA_MINBUFFER) -#define LUA_MINBUFFER 32 -#endif - - -/* -** Maximum depth for nested C calls, syntactical nested non-terminals, -** and other features implemented through recursion in C. (Value must -** fit in a 16-bit unsigned integer. It must also be compatible with -** the size of the C stack.) -*/ -#if !defined(LUAI_MAXCCALLS) -#define LUAI_MAXCCALLS 200 -#endif - - -/* -** macros that are executed whenever 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 - - -/* -** these macros allow user-specific actions when a thread is -** created/deleted/resumed/yielded. -*/ -#if !defined(luai_userstateopen) -#define luai_userstateopen(L) ((void)L) -#endif - -#if !defined(luai_userstateclose) -#define luai_userstateclose(L) ((void)L) -#endif - -#if !defined(luai_userstatethread) -#define luai_userstatethread(L,L1) ((void)L) -#endif - -#if !defined(luai_userstatefree) -#define luai_userstatefree(L,L1) ((void)L) -#endif - -#if !defined(luai_userstateresume) -#define luai_userstateresume(L,n) ((void)L) -#endif - -#if !defined(luai_userstateyield) -#define luai_userstateyield(L,n) ((void)L) -#endif - - /* ** The luai_num* macros define the primitive operations over numbers. @@ -330,24 +281,77 @@ typedef l_uint32 Instruction; +/* +** lua_numbertointeger converts a float number with an integral value +** to an integer, or returns 0 if the float is not within the range of +** a lua_Integer. (The range comparisons are tricky because of +** rounding. The tests here assume a two-complement representation, +** where MININTEGER always has an exact representation as a float; +** MAXINTEGER may not have one, and therefore its conversion to float +** may have an ill-defined value.) +*/ +#define lua_numbertointeger(n,p) \ + ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ + (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ + (*(p) = (LUA_INTEGER)(n), 1)) + /* -** macro to control inclusion of some hard tests on stack reallocation +** LUAI_FUNC is a mark for all extern functions that are not to be +** exported to outside modules. +** LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables, +** none of which to be exported to outside modules (LUAI_DDEF for +** definitions and LUAI_DDEC for declarations). +** Elf and MACH/gcc (versions 3.2 and later) mark them as "hidden" to +** optimize access when Lua is compiled as a shared library. Not all elf +** targets support this attribute. Unfortunately, gcc does not offer +** a way to check whether the target offers that support, and those +** without support give a warning about it. To avoid these warnings, +** change to the default definition. */ -#if !defined(HARDSTACKTESTS) -#define condmovestack(L,pre,pos) ((void)0) +#if !defined(LUAI_FUNC) + +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + (defined(__ELF__) || defined(__MACH__)) +#define LUAI_FUNC __attribute__((visibility("internal"))) extern #else -/* realloc stack keeping its size */ -#define condmovestack(L,pre,pos) \ - { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } +#define LUAI_FUNC extern #endif -#if !defined(HARDMEMTESTS) -#define condchangemem(L,pre,pos) ((void)0) -#else -#define condchangemem(L,pre,pos) \ - { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } -#endif +#define LUAI_DDEC(dec) LUAI_FUNC dec +#define LUAI_DDEF /* empty */ #endif + + +/* Give these macros simpler names for internal use */ +#define l_likely(x) luai_likely(x) +#define l_unlikely(x) luai_unlikely(x) + +/* +** {================================================================== +** "Abstraction Layer" for basic report of messages and errors +** =================================================================== +*/ + +/* print a string */ +#if !defined(lua_writestring) +#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#endif + +/* print a newline and flush the output */ +#if !defined(lua_writeline) +#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) +#endif + +/* print an error message */ +#if !defined(lua_writestringerror) +#define lua_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) +#endif + +/* }================================================================== */ + +#endif + diff --git a/source/external/lua/lmathlib.c b/source/external/lua/lmathlib.c deleted file mode 100644 index 5f5983a..0000000 --- a/source/external/lua/lmathlib.c +++ /dev/null @@ -1,764 +0,0 @@ -/* -** $Id: lmathlib.c $ -** Standard mathematical library -** See Copyright Notice in lua.h -*/ - -#define lmathlib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -#undef PI -#define PI (l_mathop(3.141592653589793238462643383279502884)) - - -static int math_abs (lua_State *L) { - if (lua_isinteger(L, 1)) { - lua_Integer n = lua_tointeger(L, 1); - if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n); - lua_pushinteger(L, n); - } - else - lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_sin (lua_State *L) { - lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_cos (lua_State *L) { - lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_tan (lua_State *L) { - lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_asin (lua_State *L) { - lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_acos (lua_State *L) { - lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_atan (lua_State *L) { - lua_Number y = luaL_checknumber(L, 1); - lua_Number x = luaL_optnumber(L, 2, 1); - lua_pushnumber(L, l_mathop(atan2)(y, x)); - return 1; -} - - -static int math_toint (lua_State *L) { - int valid; - lua_Integer n = lua_tointegerx(L, 1, &valid); - if (l_likely(valid)) - lua_pushinteger(L, n); - else { - luaL_checkany(L, 1); - luaL_pushfail(L); /* value is not convertible to integer */ - } - return 1; -} - - -static void pushnumint (lua_State *L, lua_Number d) { - lua_Integer n; - if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */ - lua_pushinteger(L, n); /* result is integer */ - else - lua_pushnumber(L, d); /* result is float */ -} - - -static int math_floor (lua_State *L) { - if (lua_isinteger(L, 1)) - lua_settop(L, 1); /* integer is its own floor */ - else { - lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1)); - pushnumint(L, d); - } - return 1; -} - - -static int math_ceil (lua_State *L) { - if (lua_isinteger(L, 1)) - lua_settop(L, 1); /* integer is its own ceil */ - else { - lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1)); - pushnumint(L, d); - } - return 1; -} - - -static int math_fmod (lua_State *L) { - if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) { - lua_Integer d = lua_tointeger(L, 2); - if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */ - luaL_argcheck(L, d != 0, 2, "zero"); - lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */ - } - else - lua_pushinteger(L, lua_tointeger(L, 1) % d); - } - else - lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), - luaL_checknumber(L, 2))); - return 1; -} - - -/* -** next function does not use 'modf', avoiding problems with 'double*' -** (which is not compatible with 'float*') when lua_Number is not -** 'double'. -*/ -static int math_modf (lua_State *L) { - if (lua_isinteger(L ,1)) { - lua_settop(L, 1); /* number is its own integer part */ - lua_pushnumber(L, 0); /* no fractional part */ - } - else { - lua_Number n = luaL_checknumber(L, 1); - /* integer part (rounds toward zero) */ - lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n); - pushnumint(L, ip); - /* fractional part (test needed for inf/-inf) */ - lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip)); - } - return 2; -} - - -static int math_sqrt (lua_State *L) { - lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); - return 1; -} - - -static int math_ult (lua_State *L) { - lua_Integer a = luaL_checkinteger(L, 1); - lua_Integer b = luaL_checkinteger(L, 2); - lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b); - return 1; -} - -static int math_log (lua_State *L) { - lua_Number x = luaL_checknumber(L, 1); - lua_Number res; - if (lua_isnoneornil(L, 2)) - res = l_mathop(log)(x); - else { - lua_Number base = luaL_checknumber(L, 2); -#if !defined(LUA_USE_C89) - if (base == l_mathop(2.0)) - res = l_mathop(log2)(x); - else -#endif - if (base == l_mathop(10.0)) - res = l_mathop(log10)(x); - else - res = l_mathop(log)(x)/l_mathop(log)(base); - } - lua_pushnumber(L, res); - return 1; -} - -static int math_exp (lua_State *L) { - lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_deg (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI)); - return 1; -} - -static int math_rad (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0))); - return 1; -} - - -static int math_min (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int imin = 1; /* index of current minimum value */ - int i; - luaL_argcheck(L, n >= 1, 1, "value expected"); - for (i = 2; i <= n; i++) { - if (lua_compare(L, i, imin, LUA_OPLT)) - imin = i; - } - lua_pushvalue(L, imin); - return 1; -} - - -static int math_max (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int imax = 1; /* index of current maximum value */ - int i; - luaL_argcheck(L, n >= 1, 1, "value expected"); - for (i = 2; i <= n; i++) { - if (lua_compare(L, imax, i, LUA_OPLT)) - imax = i; - } - lua_pushvalue(L, imax); - return 1; -} - - -static int math_type (lua_State *L) { - if (lua_type(L, 1) == LUA_TNUMBER) - lua_pushstring(L, (lua_isinteger(L, 1)) ? "integer" : "float"); - else { - luaL_checkany(L, 1); - luaL_pushfail(L); - } - return 1; -} - - - -/* -** {================================================================== -** Pseudo-Random Number Generator based on 'xoshiro256**'. -** =================================================================== -*/ - -/* number of binary digits in the mantissa of a float */ -#define FIGS l_floatatt(MANT_DIG) - -#if FIGS > 64 -/* there are only 64 random bits; use them all */ -#undef FIGS -#define FIGS 64 -#endif - - -/* -** LUA_RAND32 forces the use of 32-bit integers in the implementation -** of the PRN generator (mainly for testing). -*/ -#if !defined(LUA_RAND32) && !defined(Rand64) - -/* try to find an integer type with at least 64 bits */ - -#if (ULONG_MAX >> 31 >> 31) >= 3 - -/* 'long' has at least 64 bits */ -#define Rand64 unsigned long - -#elif !defined(LUA_USE_C89) && defined(LLONG_MAX) - -/* there is a 'long long' type (which must have at least 64 bits) */ -#define Rand64 unsigned long long - -#elif (LUA_MAXUNSIGNED >> 31 >> 31) >= 3 - -/* 'lua_Integer' has at least 64 bits */ -#define Rand64 lua_Unsigned - -#endif - -#endif - - -#if defined(Rand64) /* { */ - -/* -** Standard implementation, using 64-bit integers. -** If 'Rand64' has more than 64 bits, the extra bits do not interfere -** with the 64 initial bits, except in a right shift. Moreover, the -** final result has to discard the extra bits. -*/ - -/* avoid using extra bits when needed */ -#define trim64(x) ((x) & 0xffffffffffffffffu) - - -/* rotate left 'x' by 'n' bits */ -static Rand64 rotl (Rand64 x, int n) { - return (x << n) | (trim64(x) >> (64 - n)); -} - -static Rand64 nextrand (Rand64 *state) { - Rand64 state0 = state[0]; - Rand64 state1 = state[1]; - Rand64 state2 = state[2] ^ state0; - Rand64 state3 = state[3] ^ state1; - Rand64 res = rotl(state1 * 5, 7) * 9; - state[0] = state0 ^ state3; - state[1] = state1 ^ state2; - state[2] = state2 ^ (state1 << 17); - state[3] = rotl(state3, 45); - return res; -} - - -/* must take care to not shift stuff by more than 63 slots */ - - -/* -** Convert bits from a random integer into a float in the -** interval [0,1), getting the higher FIG bits from the -** random unsigned integer and converting that to a float. -*/ - -/* must throw out the extra (64 - FIGS) bits */ -#define shift64_FIG (64 - FIGS) - -/* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */ -#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) - -static lua_Number I2d (Rand64 x) { - return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG; -} - -/* convert a 'Rand64' to a 'lua_Unsigned' */ -#define I2UInt(x) ((lua_Unsigned)trim64(x)) - -/* convert a 'lua_Unsigned' to a 'Rand64' */ -#define Int2I(x) ((Rand64)(x)) - - -#else /* no 'Rand64' }{ */ - -/* get an integer with at least 32 bits */ -#if LUAI_IS32INT -typedef unsigned int lu_int32; -#else -typedef unsigned long lu_int32; -#endif - - -/* -** Use two 32-bit integers to represent a 64-bit quantity. -*/ -typedef struct Rand64 { - lu_int32 h; /* higher half */ - lu_int32 l; /* lower half */ -} Rand64; - - -/* -** If 'lu_int32' has more than 32 bits, the extra bits do not interfere -** with the 32 initial bits, except in a right shift and comparisons. -** Moreover, the final result has to discard the extra bits. -*/ - -/* avoid using extra bits when needed */ -#define trim32(x) ((x) & 0xffffffffu) - - -/* -** basic operations on 'Rand64' values -*/ - -/* build a new Rand64 value */ -static Rand64 packI (lu_int32 h, lu_int32 l) { - Rand64 result; - result.h = h; - result.l = l; - return result; -} - -/* return i << n */ -static Rand64 Ishl (Rand64 i, int n) { - lua_assert(n > 0 && n < 32); - return packI((i.h << n) | (trim32(i.l) >> (32 - n)), i.l << n); -} - -/* i1 ^= i2 */ -static void Ixor (Rand64 *i1, Rand64 i2) { - i1->h ^= i2.h; - i1->l ^= i2.l; -} - -/* return i1 + i2 */ -static Rand64 Iadd (Rand64 i1, Rand64 i2) { - Rand64 result = packI(i1.h + i2.h, i1.l + i2.l); - if (trim32(result.l) < trim32(i1.l)) /* carry? */ - result.h++; - return result; -} - -/* return i * 5 */ -static Rand64 times5 (Rand64 i) { - return Iadd(Ishl(i, 2), i); /* i * 5 == (i << 2) + i */ -} - -/* return i * 9 */ -static Rand64 times9 (Rand64 i) { - return Iadd(Ishl(i, 3), i); /* i * 9 == (i << 3) + i */ -} - -/* return 'i' rotated left 'n' bits */ -static Rand64 rotl (Rand64 i, int n) { - lua_assert(n > 0 && n < 32); - return packI((i.h << n) | (trim32(i.l) >> (32 - n)), - (trim32(i.h) >> (32 - n)) | (i.l << n)); -} - -/* for offsets larger than 32, rotate right by 64 - offset */ -static Rand64 rotl1 (Rand64 i, int n) { - lua_assert(n > 32 && n < 64); - n = 64 - n; - return packI((trim32(i.h) >> n) | (i.l << (32 - n)), - (i.h << (32 - n)) | (trim32(i.l) >> n)); -} - -/* -** implementation of 'xoshiro256**' algorithm on 'Rand64' values -*/ -static Rand64 nextrand (Rand64 *state) { - Rand64 res = times9(rotl(times5(state[1]), 7)); - Rand64 t = Ishl(state[1], 17); - Ixor(&state[2], state[0]); - Ixor(&state[3], state[1]); - Ixor(&state[1], state[2]); - Ixor(&state[0], state[3]); - Ixor(&state[2], t); - state[3] = rotl1(state[3], 45); - return res; -} - - -/* -** Converts a 'Rand64' into a float. -*/ - -/* an unsigned 1 with proper type */ -#define UONE ((lu_int32)1) - - -#if FIGS <= 32 - -/* 2^(-FIGS) */ -#define scaleFIG (l_mathop(0.5) / (UONE << (FIGS - 1))) - -/* -** get up to 32 bits from higher half, shifting right to -** throw out the extra bits. -*/ -static lua_Number I2d (Rand64 x) { - lua_Number h = (lua_Number)(trim32(x.h) >> (32 - FIGS)); - return h * scaleFIG; -} - -#else /* 32 < FIGS <= 64 */ - -/* must take care to not shift stuff by more than 31 slots */ - -/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ -#define scaleFIG \ - ((lua_Number)1.0 / (UONE << 30) / 8.0 / (UONE << (FIGS - 33))) - -/* -** use FIGS - 32 bits from lower half, throwing out the other -** (32 - (FIGS - 32)) = (64 - FIGS) bits -*/ -#define shiftLOW (64 - FIGS) - -/* -** higher 32 bits go after those (FIGS - 32) bits: shiftHI = 2^(FIGS - 32) -*/ -#define shiftHI ((lua_Number)(UONE << (FIGS - 33)) * 2.0) - - -static lua_Number I2d (Rand64 x) { - lua_Number h = (lua_Number)trim32(x.h) * shiftHI; - lua_Number l = (lua_Number)(trim32(x.l) >> shiftLOW); - return (h + l) * scaleFIG; -} - -#endif - - -/* convert a 'Rand64' to a 'lua_Unsigned' */ -static lua_Unsigned I2UInt (Rand64 x) { - return ((lua_Unsigned)trim32(x.h) << 31 << 1) | (lua_Unsigned)trim32(x.l); -} - -/* convert a 'lua_Unsigned' to a 'Rand64' */ -static Rand64 Int2I (lua_Unsigned n) { - return packI((lu_int32)(n >> 31 >> 1), (lu_int32)n); -} - -#endif /* } */ - - -/* -** A state uses four 'Rand64' values. -*/ -typedef struct { - Rand64 s[4]; -} RanState; - - -/* -** Project the random integer 'ran' into the interval [0, n]. -** Because 'ran' has 2^B possible values, the projection can only be -** uniform when the size of the interval is a power of 2 (exact -** division). Otherwise, to get a uniform projection into [0, n], we -** first compute 'lim', the smallest Mersenne number not smaller than -** 'n'. We then project 'ran' into the interval [0, lim]. If the result -** is inside [0, n], we are done. Otherwise, we try with another 'ran', -** until we have a result inside the interval. -*/ -static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, - RanState *state) { - if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */ - return ran & n; /* no bias */ - else { - lua_Unsigned lim = n; - /* compute the smallest (2^b - 1) not smaller than 'n' */ - lim |= (lim >> 1); - lim |= (lim >> 2); - lim |= (lim >> 4); - lim |= (lim >> 8); - lim |= (lim >> 16); -#if (LUA_MAXUNSIGNED >> 31) >= 3 - lim |= (lim >> 32); /* integer type has more than 32 bits */ -#endif - lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ - && lim >= n /* not smaller than 'n', */ - && (lim >> 1) < n); /* and it is the smallest one */ - while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ - ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ - return ran; - } -} - - -static int math_random (lua_State *L) { - lua_Integer low, up; - lua_Unsigned p; - RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); - Rand64 rv = nextrand(state->s); /* next pseudo-random value */ - switch (lua_gettop(L)) { /* check number of arguments */ - case 0: { /* no arguments */ - lua_pushnumber(L, I2d(rv)); /* float between 0 and 1 */ - return 1; - } - case 1: { /* only upper limit */ - low = 1; - up = luaL_checkinteger(L, 1); - if (up == 0) { /* single 0 as argument? */ - lua_pushinteger(L, I2UInt(rv)); /* full random integer */ - return 1; - } - break; - } - case 2: { /* lower and upper limits */ - low = luaL_checkinteger(L, 1); - up = luaL_checkinteger(L, 2); - break; - } - default: return luaL_error(L, "wrong number of arguments"); - } - /* random integer in the interval [low, up] */ - luaL_argcheck(L, low <= up, 1, "interval is empty"); - /* project random integer into the interval [0, up - low] */ - p = project(I2UInt(rv), (lua_Unsigned)up - (lua_Unsigned)low, state); - lua_pushinteger(L, p + (lua_Unsigned)low); - return 1; -} - - -static void setseed (lua_State *L, Rand64 *state, - lua_Unsigned n1, lua_Unsigned n2) { - int i; - state[0] = Int2I(n1); - state[1] = Int2I(0xff); /* avoid a zero state */ - state[2] = Int2I(n2); - state[3] = Int2I(0); - for (i = 0; i < 16; i++) - nextrand(state); /* discard initial values to "spread" seed */ - lua_pushinteger(L, n1); - lua_pushinteger(L, n2); -} - - -/* -** Set a "random" seed. To get some randomness, use the current time -** and the address of 'L' (in case the machine does address space layout -** randomization). -*/ -static void randseed (lua_State *L, RanState *state) { - lua_Unsigned seed1 = (lua_Unsigned)time(NULL); - lua_Unsigned seed2 = (lua_Unsigned)(size_t)L; - setseed(L, state->s, seed1, seed2); -} - - -static int math_randomseed (lua_State *L) { - RanState *state = (RanState *)lua_touserdata(L, lua_upvalueindex(1)); - if (lua_isnone(L, 1)) { - randseed(L, state); - } - else { - lua_Integer n1 = luaL_checkinteger(L, 1); - lua_Integer n2 = luaL_optinteger(L, 2, 0); - setseed(L, state->s, n1, n2); - } - return 2; /* return seeds */ -} - - -static const luaL_Reg randfuncs[] = { - {"random", math_random}, - {"randomseed", math_randomseed}, - {NULL, NULL} -}; - - -/* -** Register the random functions and initialize their state. -*/ -static void setrandfunc (lua_State *L) { - RanState *state = (RanState *)lua_newuserdatauv(L, sizeof(RanState), 0); - randseed(L, state); /* initialize with a "random" seed */ - lua_pop(L, 2); /* remove pushed seeds */ - luaL_setfuncs(L, randfuncs, 1); -} - -/* }================================================================== */ - - -/* -** {================================================================== -** Deprecated functions (for compatibility only) -** =================================================================== -*/ -#if defined(LUA_COMPAT_MATHLIB) - -static int math_cosh (lua_State *L) { - lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_sinh (lua_State *L) { - lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_tanh (lua_State *L) { - lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); - return 1; -} - -static int math_pow (lua_State *L) { - lua_Number x = luaL_checknumber(L, 1); - lua_Number y = luaL_checknumber(L, 2); - lua_pushnumber(L, l_mathop(pow)(x, y)); - return 1; -} - -static int math_frexp (lua_State *L) { - int e; - lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); - lua_pushinteger(L, e); - return 2; -} - -static int math_ldexp (lua_State *L) { - lua_Number x = luaL_checknumber(L, 1); - int ep = (int)luaL_checkinteger(L, 2); - lua_pushnumber(L, l_mathop(ldexp)(x, ep)); - return 1; -} - -static int math_log10 (lua_State *L) { - lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); - return 1; -} - -#endif -/* }================================================================== */ - - - -static const luaL_Reg mathlib[] = { - {"abs", math_abs}, - {"acos", math_acos}, - {"asin", math_asin}, - {"atan", math_atan}, - {"ceil", math_ceil}, - {"cos", math_cos}, - {"deg", math_deg}, - {"exp", math_exp}, - {"tointeger", math_toint}, - {"floor", math_floor}, - {"fmod", math_fmod}, - {"ult", math_ult}, - {"log", math_log}, - {"max", math_max}, - {"min", math_min}, - {"modf", math_modf}, - {"rad", math_rad}, - {"sin", math_sin}, - {"sqrt", math_sqrt}, - {"tan", math_tan}, - {"type", math_type}, -#if defined(LUA_COMPAT_MATHLIB) - {"atan2", math_atan}, - {"cosh", math_cosh}, - {"sinh", math_sinh}, - {"tanh", math_tanh}, - {"pow", math_pow}, - {"frexp", math_frexp}, - {"ldexp", math_ldexp}, - {"log10", math_log10}, -#endif - /* placeholders */ - {"random", NULL}, - {"randomseed", NULL}, - {"pi", NULL}, - {"huge", NULL}, - {"maxinteger", NULL}, - {"mininteger", NULL}, - {NULL, NULL} -}; - - -/* -** Open math library -*/ -LUAMOD_API int luaopen_math (lua_State *L) { - luaL_newlib(L, mathlib); - lua_pushnumber(L, PI); - lua_setfield(L, -2, "pi"); - lua_pushnumber(L, (lua_Number)HUGE_VAL); - lua_setfield(L, -2, "huge"); - lua_pushinteger(L, LUA_MAXINTEGER); - lua_setfield(L, -2, "maxinteger"); - lua_pushinteger(L, LUA_MININTEGER); - lua_setfield(L, -2, "mininteger"); - setrandfunc(L); - return 1; -} - diff --git a/source/external/lua/lmem.c b/source/external/lua/lmem.c deleted file mode 100644 index 9029d58..0000000 --- a/source/external/lua/lmem.c +++ /dev/null @@ -1,201 +0,0 @@ -/* -** $Id: lmem.c $ -** Interface to Memory Manager -** See Copyright Notice in lua.h -*/ - -#define lmem_c -#define LUA_CORE - -#include "lprefix.h" - - -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" - - -#if defined(EMERGENCYGCTESTS) -/* -** First allocation will fail whenever not building initial state. -** (This fail will trigger 'tryagain' and a full GC cycle at every -** allocation.) -*/ -static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { - if (completestate(g) && ns > 0) /* frees never fail */ - return NULL; /* fail */ - else /* normal allocation */ - return (*g->frealloc)(g->ud, block, os, ns); -} -#else -#define firsttry(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) -#endif - - - - - -/* -** About the realloc function: -** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize); -** ('osize' is the old size, 'nsize' is the new size) -** -** - frealloc(ud, p, x, 0) frees the block 'p' and returns NULL. -** Particularly, frealloc(ud, NULL, 0, 0) does nothing, -** which is equivalent to free(NULL) in ISO C. -** -** - frealloc(ud, NULL, x, s) creates a new block of size 's' -** (no matter 'x'). Returns NULL if it cannot create the new block. -** -** - otherwise, frealloc(ud, b, x, y) reallocates the block 'b' from -** size 'x' to size 'y'. Returns NULL if it cannot reallocate the -** block to the new size. -*/ - - - - -/* -** {================================================================== -** Functions to allocate/deallocate arrays for the Parser -** =================================================================== -*/ - -/* -** Minimum size for arrays during parsing, to avoid overhead of -** reallocating to size 1, then 2, and then 4. All these arrays -** will be reallocated to exact sizes or erased when parsing ends. -*/ -#define MINSIZEARRAY 4 - - -void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, - int size_elems, int limit, const char *what) { - void *newblock; - int size = *psize; - if (nelems + 1 <= size) /* does one extra element still fit? */ - return block; /* nothing to be done */ - if (size >= limit / 2) { /* cannot double it? */ - if (l_unlikely(size >= limit)) /* cannot grow even a little? */ - luaG_runerror(L, "too many %s (limit is %d)", what, limit); - size = limit; /* still have at least one free place */ - } - else { - size *= 2; - if (size < MINSIZEARRAY) - size = MINSIZEARRAY; /* minimum size */ - } - lua_assert(nelems + 1 <= size && size <= limit); - /* 'limit' ensures that multiplication will not overflow */ - newblock = luaM_saferealloc_(L, block, cast_sizet(*psize) * size_elems, - cast_sizet(size) * size_elems); - *psize = size; /* update only when everything else is OK */ - return newblock; -} - - -/* -** In prototypes, the size of the array is also its number of -** elements (to save memory). So, if it cannot shrink an array -** to its number of elements, the only option is to raise an -** error. -*/ -void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, - int final_n, int size_elem) { - void *newblock; - size_t oldsize = cast_sizet((*size) * size_elem); - size_t newsize = cast_sizet(final_n * size_elem); - lua_assert(newsize <= oldsize); - newblock = luaM_saferealloc_(L, block, oldsize, newsize); - *size = final_n; - return newblock; -} - -/* }================================================================== */ - - -l_noret luaM_toobig (lua_State *L) { - luaG_runerror(L, "memory allocation error: block too big"); -} - - -/* -** Free memory -*/ -void luaM_free_ (lua_State *L, void *block, size_t osize) { - global_State *g = G(L); - lua_assert((osize == 0) == (block == NULL)); - (*g->frealloc)(g->ud, block, osize, 0); - g->GCdebt -= osize; -} - - -/* -** In case of allocation fail, this function will do an emergency -** collection to free some memory and then try the allocation again. -** The GC should not be called while state is not fully built, as the -** collector is not yet fully initialized. Also, it should not be called -** when 'gcstopem' is true, because then the interpreter is in the -** middle of a collection step. -*/ -static void *tryagain (lua_State *L, void *block, - size_t osize, size_t nsize) { - global_State *g = G(L); - if (completestate(g) && !g->gcstopem) { - luaC_fullgc(L, 1); /* try to free some memory... */ - return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ - } - else return NULL; /* cannot free any memory without a full state */ -} - - -/* -** Generic allocation routine. -*/ -void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { - void *newblock; - global_State *g = G(L); - lua_assert((osize == 0) == (block == NULL)); - newblock = firsttry(g, block, osize, nsize); - if (l_unlikely(newblock == NULL && nsize > 0)) { - newblock = tryagain(L, block, osize, nsize); - if (newblock == NULL) /* still no memory? */ - return NULL; /* do not update 'GCdebt' */ - } - lua_assert((nsize == 0) == (newblock == NULL)); - g->GCdebt = (g->GCdebt + nsize) - osize; - return newblock; -} - - -void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, - size_t nsize) { - void *newblock = luaM_realloc_(L, block, osize, nsize); - if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ - luaM_error(L); - return newblock; -} - - -void *luaM_malloc_ (lua_State *L, size_t size, int tag) { - if (size == 0) - return NULL; /* that's all */ - else { - global_State *g = G(L); - void *newblock = firsttry(g, NULL, tag, size); - if (l_unlikely(newblock == NULL)) { - newblock = tryagain(L, NULL, tag, size); - if (newblock == NULL) - luaM_error(L); - } - g->GCdebt += size; - return newblock; - } -} diff --git a/source/external/lua/lmem.h b/source/external/lua/lmem.h index 8c75a44..dc714fb 100644 --- a/source/external/lua/lmem.h +++ b/source/external/lua/lmem.h @@ -39,11 +39,11 @@ ** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that ** the result is not larger than 'n' and cannot overflow a 'size_t' ** when multiplied by the size of type 't'. (Assumes that 'n' is an -** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) +** 'int' and that 'int' is not larger than 'size_t'.) */ #define luaM_limitN(n,t) \ ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ - cast_uint((MAX_SIZET/sizeof(t)))) + cast_int((MAX_SIZET/sizeof(t)))) /* @@ -57,12 +57,15 @@ #define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) #define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) -#define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) +#define luaM_newvector(L,n,t) \ + cast(t*, luaM_malloc_(L, cast_sizet(n)*sizeof(t), 0)) #define luaM_newvectorchecked(L,n,t) \ (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) #define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) +#define luaM_newblock(L, size) luaM_newvector(L, size, char) + #define luaM_growvector(L,v,nelems,size,t,limit,e) \ ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ luaM_limitN(limit,t),e))) @@ -83,10 +86,10 @@ LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, size_t size); LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, - int *size, int size_elem, int limit, + int *size, unsigned size_elem, int limit, const char *what); LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, - int final_n, int size_elem); + int final_n, unsigned size_elem); LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); #endif diff --git a/source/external/lua/loadlib.c b/source/external/lua/loadlib.c deleted file mode 100644 index cb28045..0000000 --- a/source/external/lua/loadlib.c +++ /dev/null @@ -1,872 +0,0 @@ -/* -** $Id: loadlib.c $ -** Dynamic library loader for Lua -** See Copyright Notice in lua.h -** -** This module contains an implementation of loadlib for Unix systems -** that have dlfcn, an implementation for Windows, and a stub for other -** systems. -*/ - -#define loadlib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* -** LUA_IGMARK is a mark to ignore all before it when building the -** luaopen_ function name. -*/ -#if !defined (LUA_IGMARK) -#define LUA_IGMARK "-" -#endif - - -/* -** LUA_CSUBSEP is the character that replaces dots in submodule names -** when searching for a C loader. -** LUA_LSUBSEP is the character that replaces dots in submodule names -** when searching for a Lua loader. -*/ -#if !defined(LUA_CSUBSEP) -#define LUA_CSUBSEP LUA_DIRSEP -#endif - -#if !defined(LUA_LSUBSEP) -#define LUA_LSUBSEP LUA_DIRSEP -#endif - - -/* prefix for open functions in C libraries */ -#define LUA_POF "luaopen_" - -/* separator for open functions in C libraries */ -#define LUA_OFSEP "_" - - -/* -** key for table in the registry that keeps handles -** for all loaded C libraries -*/ -static const char *const CLIBS = "_CLIBS"; - -#define LIB_FAIL "open" - - -#define setprogdir(L) ((void)0) - - -/* -** Special type equivalent to '(void*)' for functions in gcc -** (to suppress warnings when converting function pointers) -*/ -typedef void (*voidf)(void); - - -/* -** system-dependent functions -*/ - -/* -** unload library 'lib' -*/ -static void lsys_unloadlib (void *lib); - -/* -** load C library in file 'path'. If 'seeglb', load with all names in -** the library global. -** Returns the library; in case of error, returns NULL plus an -** error string in the stack. -*/ -static void *lsys_load (lua_State *L, const char *path, int seeglb); - -/* -** Try to find a function named 'sym' in library 'lib'. -** Returns the function; in case of error, returns NULL plus an -** error string in the stack. -*/ -static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym); - - - - -#if defined(LUA_USE_DLOPEN) /* { */ -/* -** {======================================================================== -** This is an implementation of loadlib based on the dlfcn interface. -** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, -** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least -** as an emulation layer on top of native functions. -** ========================================================================= -*/ - -#include - -/* -** 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__) -#define cast_func(p) (__extension__ (lua_CFunction)(p)) -#else -#define cast_func(p) ((lua_CFunction)(p)) -#endif - - -static void lsys_unloadlib (void *lib) { - dlclose(lib); -} - - -static void *lsys_load (lua_State *L, const char *path, int seeglb) { - void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); - if (l_unlikely(lib == NULL)) - lua_pushstring(L, dlerror()); - return lib; -} - - -static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { - lua_CFunction f = cast_func(dlsym(lib, sym)); - if (l_unlikely(f == NULL)) - lua_pushstring(L, dlerror()); - return f; -} - -/* }====================================================== */ - - - -#elif defined(LUA_DL_DLL) /* }{ */ -/* -** {====================================================================== -** This is an implementation of loadlib for Windows using native functions. -** ======================================================================= -*/ - -#include - - -/* -** optional flags for LoadLibraryEx -*/ -#if !defined(LUA_LLE_FLAGS) -#define LUA_LLE_FLAGS 0 -#endif - - -#undef setprogdir - - -/* -** Replace in the path (on the top of the stack) any occurrence -** of LUA_EXEC_DIR with the executable's path. -*/ -static void setprogdir (lua_State *L) { - char buff[MAX_PATH + 1]; - char *lb; - DWORD nsize = sizeof(buff)/sizeof(char); - DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */ - if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) - luaL_error(L, "unable to get ModuleFileName"); - else { - *lb = '\0'; /* cut name on the last '\\' to get the path */ - luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); - lua_remove(L, -2); /* remove original string */ - } -} - - - - -static void pusherror (lua_State *L) { - int error = GetLastError(); - char buffer[128]; - if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) - lua_pushstring(L, buffer); - else - lua_pushfstring(L, "system error %d\n", error); -} - -static void lsys_unloadlib (void *lib) { - FreeLibrary((HMODULE)lib); -} - - -static void *lsys_load (lua_State *L, const char *path, int seeglb) { - HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); - (void)(seeglb); /* not used: symbols are 'global' by default */ - if (lib == NULL) pusherror(L); - return lib; -} - - -static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { - lua_CFunction f = (lua_CFunction)(voidf)GetProcAddress((HMODULE)lib, sym); - if (f == NULL) pusherror(L); - return f; -} - -/* }====================================================== */ - - -#else /* }{ */ -/* -** {====================================================== -** Fallback for other systems -** ======================================================= -*/ - -#undef LIB_FAIL -#define LIB_FAIL "absent" - - -#define DLMSG "dynamic libraries not enabled; check your Lua installation" - - -static void lsys_unloadlib (void *lib) { - (void)(lib); /* not used */ -} - - -static void *lsys_load (lua_State *L, const char *path, int seeglb) { - (void)(path); (void)(seeglb); /* not used */ - lua_pushliteral(L, DLMSG); - return NULL; -} - - -static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) { - (void)(lib); (void)(sym); /* not used */ - lua_pushliteral(L, DLMSG); - return NULL; -} - -/* }====================================================== */ -#endif /* } */ - - -/* -** {================================================================== -** Set Paths -** =================================================================== -*/ - -/* -** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment -** variables that Lua check to set its paths. -*/ -#if !defined(LUA_PATH_VAR) -#define LUA_PATH_VAR "LUA_PATH" -#endif - -#if !defined(LUA_CPATH_VAR) -#define LUA_CPATH_VAR "LUA_CPATH" -#endif - - - -/* -** return registry.LUA_NOENV as a boolean -*/ -static int noenv (lua_State *L) { - int b; - lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); - b = lua_toboolean(L, -1); - lua_pop(L, 1); /* remove value */ - return b; -} - - -/* -** Set a path -*/ -static void setpath (lua_State *L, const char *fieldname, - const char *envname, - const char *dft) { - const char *dftmark; - const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX); - const char *path = getenv(nver); /* try versioned name */ - if (path == NULL) /* no versioned environment variable? */ - path = getenv(envname); /* try unversioned name */ - if (path == NULL || noenv(L)) /* no environment variable? */ - lua_pushstring(L, dft); /* use default */ - else if ((dftmark = strstr(path, LUA_PATH_SEP LUA_PATH_SEP)) == NULL) - lua_pushstring(L, path); /* nothing to change */ - else { /* path contains a ";;": insert default path in its place */ - size_t len = strlen(path); - luaL_Buffer b; - luaL_buffinit(L, &b); - if (path < dftmark) { /* is there a prefix before ';;'? */ - luaL_addlstring(&b, path, dftmark - path); /* add it */ - luaL_addchar(&b, *LUA_PATH_SEP); - } - luaL_addstring(&b, dft); /* add default */ - if (dftmark < path + len - 2) { /* is there a suffix after ';;'? */ - luaL_addchar(&b, *LUA_PATH_SEP); - luaL_addlstring(&b, dftmark + 2, (path + len - 2) - dftmark); - } - luaL_pushresult(&b); - } - setprogdir(L); - lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */ - lua_pop(L, 1); /* pop versioned variable name ('nver') */ -} - -/* }================================================================== */ - - -/* -** return registry.CLIBS[path] -*/ -static void *checkclib (lua_State *L, const char *path) { - void *plib; - lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); - lua_getfield(L, -1, path); - plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ - lua_pop(L, 2); /* pop CLIBS table and 'plib' */ - return plib; -} - - -/* -** registry.CLIBS[path] = plib -- for queries -** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries -*/ -static void addtoclib (lua_State *L, const char *path, void *plib) { - lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); - lua_pushlightuserdata(L, plib); - lua_pushvalue(L, -1); - lua_setfield(L, -3, path); /* CLIBS[path] = plib */ - lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ - lua_pop(L, 1); /* pop CLIBS table */ -} - - -/* -** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib -** handles in list CLIBS -*/ -static int gctm (lua_State *L) { - lua_Integer n = luaL_len(L, 1); - for (; n >= 1; n--) { /* for each handle, in reverse order */ - lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ - lsys_unloadlib(lua_touserdata(L, -1)); - lua_pop(L, 1); /* pop handle */ - } - return 0; -} - - - -/* error codes for 'lookforfunc' */ -#define ERRLIB 1 -#define ERRFUNC 2 - -/* -** Look for a C function named 'sym' in a dynamically loaded library -** 'path'. -** First, check whether the library is already loaded; if not, try -** to load it. -** Then, if 'sym' is '*', return true (as library has been loaded). -** Otherwise, look for symbol 'sym' in the library and push a -** C function with that symbol. -** Return 0 and 'true' or a function in the stack; in case of -** errors, return an error code and an error message in the stack. -*/ -static int lookforfunc (lua_State *L, const char *path, const char *sym) { - void *reg = checkclib(L, path); /* check loaded C libraries */ - if (reg == NULL) { /* must load library? */ - reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */ - if (reg == NULL) return ERRLIB; /* unable to load library */ - addtoclib(L, path, reg); - } - if (*sym == '*') { /* loading only library (no function)? */ - lua_pushboolean(L, 1); /* return 'true' */ - return 0; /* no errors */ - } - else { - lua_CFunction f = lsys_sym(L, reg, sym); - if (f == NULL) - return ERRFUNC; /* unable to find function */ - lua_pushcfunction(L, f); /* else create new function */ - return 0; /* no errors */ - } -} - - -static int ll_loadlib (lua_State *L) { - const char *path = luaL_checkstring(L, 1); - const char *init = luaL_checkstring(L, 2); - int stat = lookforfunc(L, path, init); - if (l_likely(stat == 0)) /* no errors? */ - return 1; /* return the loaded function */ - else { /* error; error message is on stack top */ - luaL_pushfail(L); - lua_insert(L, -2); - lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); - return 3; /* return fail, error message, and where */ - } -} - - - -/* -** {====================================================== -** 'require' function -** ======================================================= -*/ - - -static int readable (const char *filename) { - FILE *f = fopen(filename, "r"); /* try to open file */ - if (f == NULL) return 0; /* open failed */ - fclose(f); - return 1; -} - - -/* -** Get the next name in '*path' = 'name1;name2;name3;...', changing -** the ending ';' to '\0' to create a zero-terminated string. Return -** NULL when list ends. -*/ -static const char *getnextfilename (char **path, char *end) { - char *sep; - char *name = *path; - if (name == end) - return NULL; /* no more names */ - else if (*name == '\0') { /* from previous iteration? */ - *name = *LUA_PATH_SEP; /* restore separator */ - name++; /* skip it */ - } - sep = strchr(name, *LUA_PATH_SEP); /* find next separator */ - if (sep == NULL) /* separator not found? */ - sep = end; /* name goes until the end */ - *sep = '\0'; /* finish file name */ - *path = sep; /* will start next search from here */ - return name; -} - - -/* -** Given a path such as ";blabla.so;blublu.so", pushes the string -** -** no file 'blabla.so' -** no file 'blublu.so' -*/ -static void pusherrornotfound (lua_State *L, const char *path) { - luaL_Buffer b; - luaL_buffinit(L, &b); - luaL_addstring(&b, "no file '"); - luaL_addgsub(&b, path, LUA_PATH_SEP, "'\n\tno file '"); - luaL_addstring(&b, "'"); - luaL_pushresult(&b); -} - - -static const char *searchpath (lua_State *L, const char *name, - const char *path, - const char *sep, - const char *dirsep) { - luaL_Buffer buff; - char *pathname; /* path with name inserted */ - char *endpathname; /* its end */ - const char *filename; - /* separator is non-empty and appears in 'name'? */ - if (*sep != '\0' && strchr(name, *sep) != NULL) - name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ - luaL_buffinit(L, &buff); - /* add path to the buffer, replacing marks ('?') with the file name */ - luaL_addgsub(&buff, path, LUA_PATH_MARK, name); - luaL_addchar(&buff, '\0'); - pathname = luaL_buffaddr(&buff); /* writable list of file names */ - endpathname = pathname + luaL_bufflen(&buff) - 1; - while ((filename = getnextfilename(&pathname, endpathname)) != NULL) { - if (readable(filename)) /* does file exist and is readable? */ - return lua_pushstring(L, filename); /* save and return name */ - } - luaL_pushresult(&buff); /* push path to create error message */ - pusherrornotfound(L, lua_tostring(L, -1)); /* create error message */ - return NULL; /* not found */ -} - - -static int ll_searchpath (lua_State *L) { - const char *f = searchpath(L, luaL_checkstring(L, 1), - luaL_checkstring(L, 2), - luaL_optstring(L, 3, "."), - luaL_optstring(L, 4, LUA_DIRSEP)); - if (f != NULL) return 1; - else { /* error message is on top of the stack */ - luaL_pushfail(L); - lua_insert(L, -2); - return 2; /* return fail + error message */ - } -} - - -static const char *findfile (lua_State *L, const char *name, - const char *pname, - const char *dirsep) { - const char *path; - lua_getfield(L, lua_upvalueindex(1), pname); - path = lua_tostring(L, -1); - if (l_unlikely(path == NULL)) - luaL_error(L, "'package.%s' must be a string", pname); - return searchpath(L, name, path, ".", dirsep); -} - - -static int checkload (lua_State *L, int stat, const char *filename) { - if (l_likely(stat)) { /* module loaded successfully? */ - lua_pushstring(L, filename); /* will be 2nd argument to module */ - return 2; /* return open function and file name */ - } - else - return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s", - lua_tostring(L, 1), filename, lua_tostring(L, -1)); -} - - -static int searcher_Lua (lua_State *L) { - const char *filename; - const char *name = luaL_checkstring(L, 1); - filename = findfile(L, name, "path", LUA_LSUBSEP); - if (filename == NULL) return 1; /* module not found in this path */ - return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); -} - - -/* -** Try to find a load function for module 'modname' at file 'filename'. -** First, change '.' to '_' in 'modname'; then, if 'modname' has -** the form X-Y (that is, it has an "ignore mark"), build a function -** name "luaopen_X" and look for it. (For compatibility, if that -** fails, it also tries "luaopen_Y".) If there is no ignore mark, -** look for a function named "luaopen_modname". -*/ -static int loadfunc (lua_State *L, const char *filename, const char *modname) { - const char *openfunc; - const char *mark; - modname = luaL_gsub(L, modname, ".", LUA_OFSEP); - mark = strchr(modname, *LUA_IGMARK); - if (mark) { - int stat; - openfunc = lua_pushlstring(L, modname, mark - modname); - openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc); - stat = lookforfunc(L, filename, openfunc); - if (stat != ERRFUNC) return stat; - modname = mark + 1; /* else go ahead and try old-style name */ - } - openfunc = lua_pushfstring(L, LUA_POF"%s", modname); - return lookforfunc(L, filename, openfunc); -} - - -static int searcher_C (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); - if (filename == NULL) return 1; /* module not found in this path */ - return checkload(L, (loadfunc(L, filename, name) == 0), filename); -} - - -static int searcher_Croot (lua_State *L) { - const char *filename; - const char *name = luaL_checkstring(L, 1); - const char *p = strchr(name, '.'); - int stat; - if (p == NULL) return 0; /* is root */ - lua_pushlstring(L, name, p - name); - filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); - if (filename == NULL) return 1; /* root not found */ - if ((stat = loadfunc(L, filename, name)) != 0) { - if (stat != ERRFUNC) - return checkload(L, 0, filename); /* real error */ - else { /* open function not found */ - lua_pushfstring(L, "no module '%s' in file '%s'", name, filename); - return 1; - } - } - lua_pushstring(L, filename); /* will be 2nd argument to module */ - return 2; -} - - -static int searcher_preload (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); - if (lua_getfield(L, -1, name) == LUA_TNIL) { /* not found? */ - lua_pushfstring(L, "no field package.preload['%s']", name); - return 1; - } - else { - lua_pushliteral(L, ":preload:"); - return 2; - } -} - - -static void findloader (lua_State *L, const char *name) { - int i; - luaL_Buffer msg; /* to build error message */ - /* push 'package.searchers' to index 3 in the stack */ - if (l_unlikely(lua_getfield(L, lua_upvalueindex(1), "searchers") - != LUA_TTABLE)) - luaL_error(L, "'package.searchers' must be a table"); - luaL_buffinit(L, &msg); - /* iterate over available searchers to find a loader */ - for (i = 1; ; i++) { - luaL_addstring(&msg, "\n\t"); /* error-message prefix */ - if (l_unlikely(lua_rawgeti(L, 3, i) == LUA_TNIL)) { /* no more searchers? */ - lua_pop(L, 1); /* remove nil */ - luaL_buffsub(&msg, 2); /* remove prefix */ - luaL_pushresult(&msg); /* create error message */ - luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1)); - } - lua_pushstring(L, name); - lua_call(L, 1, 2); /* call it */ - if (lua_isfunction(L, -2)) /* did it find a loader? */ - return; /* module loader found */ - else if (lua_isstring(L, -2)) { /* searcher returned error message? */ - lua_pop(L, 1); /* remove extra return */ - luaL_addvalue(&msg); /* concatenate error message */ - } - else { /* no error message */ - lua_pop(L, 2); /* remove both returns */ - luaL_buffsub(&msg, 2); /* remove prefix */ - } - } -} - -// [RZC 12/03/2026] ================================== -// Soport per a rutes relatives i absolutes -// -static void resolve_module_name(lua_State *L, char *out, size_t outsz) { - const char *req = luaL_checkstring(L, 1); - - // 1. RUTA ABSOLUTA: empieza por ':' - if (req[0] == ':') { - strncpy(out, req + 1, outsz - 1); - out[outsz - 1] = '\0'; - return; - } - - // 2. Obtener módulo llamador - lua_Debug ar; - if (!lua_getstack(L, 1, &ar)) { - // No hay llamador → usar nombre tal cual - strncpy(out, req, outsz - 1); - out[outsz - 1] = '\0'; - return; - } - - lua_getinfo(L, "S", &ar); - - // ar.source contiene algo como "@ia.test" o "@main" - const char *src = ar.source; - if (!src) { - // No viene de archivo → usar nombre tal cual - strncpy(out, req, outsz - 1); - out[outsz - 1] = '\0'; - return; - } - - // Quitar '@' - //src++; - - // 3. Extraer directorio del módulo llamador - // Ej: "ia.tools.other" → "ia.tools" - char caller[256]; - strncpy(caller, src, sizeof(caller) - 1); - caller[sizeof(caller) - 1] = '\0'; - - char *lastdot = strrchr(caller, '.'); - if (lastdot) - *lastdot = '\0'; // dejar solo el directorio - else - caller[0] = '\0'; // está en la raíz - - // 4. RUTA RELATIVA HACIA ARRIBA: empieza por ".." - if (req[0] == '.' && req[1] == '.') { - // Contar cuántos '.' consecutivos hay - int up = 0; - while (req[up] == '.') - up++; - - // up = número de puntos → niveles a subir - // Ej: "..test" → up=2 → subir 1 nivel - // "...main" → up=3 → subir 2 niveles - - int levels = up - 1; - - // Copiar caller a buffer temporal - char temp[256]; - strncpy(temp, caller, sizeof(temp) - 1); - temp[sizeof(temp) - 1] = '\0'; - - // Subir niveles - for (int i = 0; i < levels; i++) { - char *p = strrchr(temp, '.'); - if (p) - *p = '\0'; - else { - temp[0] = '\0'; - break; - } - } - - // Concatenar lo que queda después de los puntos - const char *rest = req + up; - - if (temp[0] == '\0') { - // Hemos llegado a la raíz - strncpy(out, rest, outsz - 1); - } else { - snprintf(out, outsz, "%s.%s", temp, rest); - } - - out[outsz - 1] = '\0'; - return; - } - - // 5. RUTA RELATIVA NORMAL (no empieza por ':' ni por '..') - if (caller[0] == '\0') { - // Estamos en la raíz - strncpy(out, req, outsz - 1); - } else { - snprintf(out, outsz, "%s.%s", caller, req); - } - - out[outsz - 1] = '\0'; -} -// =================================================== - -static int ll_require (lua_State *L) { - // [RZC 12/03/2026] ================================== - // Soport per a rutes relatives i absolutes - // - //const char *name = luaL_checkstring(L, 1); - char resolved[256]; - resolve_module_name(L, resolved, sizeof(resolved)); - const char *name = resolved; - // =================================================== - - lua_settop(L, 1); /* LOADED table will be at index 2 */ - lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); - lua_getfield(L, 2, name); /* LOADED[name] */ - if (lua_toboolean(L, -1)) /* is it there? */ - return 1; /* package is already loaded */ - /* else must load package */ - lua_pop(L, 1); /* remove 'getfield' result */ - findloader(L, name); - lua_rotate(L, -2, 1); /* function <-> loader data */ - lua_pushvalue(L, 1); /* name is 1st argument to module loader */ - lua_pushvalue(L, -3); /* loader data is 2nd argument */ - /* stack: ...; loader data; loader function; mod. name; loader data */ - lua_call(L, 2, 1); /* run loader to load module */ - /* stack: ...; loader data; result from loader */ - if (!lua_isnil(L, -1)) /* non-nil return? */ - lua_setfield(L, 2, name); /* LOADED[name] = returned value */ - else - lua_pop(L, 1); /* pop nil */ - if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ - lua_pushboolean(L, 1); /* use true as result */ - lua_copy(L, -1, -2); /* replace loader result */ - lua_setfield(L, 2, name); /* LOADED[name] = true */ - } - lua_rotate(L, -2, 1); /* loader data <-> module result */ - return 2; /* return module result and loader data */ -} - -/* }====================================================== */ - - - - -static const luaL_Reg pk_funcs[] = { - {"loadlib", ll_loadlib}, - {"searchpath", ll_searchpath}, - /* placeholders */ - {"preload", NULL}, - {"cpath", NULL}, - {"path", NULL}, - {"searchers", NULL}, - {"loaded", NULL}, - {NULL, NULL} -}; - - -static const luaL_Reg ll_funcs[] = { - {"require", ll_require}, - {NULL, NULL} -}; - - -static void createsearcherstable (lua_State *L) { - static const lua_CFunction searchers[] = - {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; - int i; - /* create 'searchers' table */ - lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); - /* fill it with predefined searchers */ - for (i=0; searchers[i] != NULL; i++) { - lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ - lua_pushcclosure(L, searchers[i], 1); - lua_rawseti(L, -2, i+1); - } - lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ -} - - -/* -** create table CLIBS to keep track of loaded C libraries, -** setting a finalizer to close all libraries when closing state. -*/ -static void createclibstable (lua_State *L) { - luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */ - lua_createtable(L, 0, 1); /* create metatable for CLIBS */ - lua_pushcfunction(L, gctm); - lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ - lua_setmetatable(L, -2); -} - - -LUAMOD_API int luaopen_package (lua_State *L) { - createclibstable(L); - luaL_newlib(L, pk_funcs); /* create 'package' table */ - createsearcherstable(L); - /* set paths */ - setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT); - setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT); - /* store config information */ - lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" - LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); - lua_setfield(L, -2, "config"); - /* set field 'loaded' */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); - lua_setfield(L, -2, "loaded"); - /* set field 'preload' */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); - lua_setfield(L, -2, "preload"); - lua_pushglobaltable(L); - lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ - luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ - lua_pop(L, 1); /* pop global table */ - return 1; /* return 'package' table */ -} - diff --git a/source/external/lua/lobject.c b/source/external/lua/lobject.c deleted file mode 100644 index 0e504be..0000000 --- a/source/external/lua/lobject.c +++ /dev/null @@ -1,592 +0,0 @@ -/* -** $Id: lobject.c $ -** Some generic functions over Lua objects -** See Copyright Notice in lua.h -*/ - -#define lobject_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include -#include -#include -#include -#include - -#include "lua.h" - -#include "lctype.h" -#include "ldebug.h" -#include "ldo.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "lvm.h" - - -/* -** Computes ceil(log2(x)) -*/ -int luaO_ceillog2 (unsigned int x) { - 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, - 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, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 - }; - int l = 0; - x--; - while (x >= 256) { l += 8; x >>= 8; } - return l + log_2[x]; -} - - -static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, - lua_Integer v2) { - switch (op) { - case LUA_OPADD: return intop(+, v1, v2); - case LUA_OPSUB:return intop(-, v1, v2); - case LUA_OPMUL:return intop(*, v1, v2); - case LUA_OPMOD: return luaV_mod(L, v1, v2); - case LUA_OPIDIV: return luaV_idiv(L, v1, v2); - case LUA_OPBAND: return intop(&, v1, v2); - case LUA_OPBOR: return intop(|, v1, v2); - case LUA_OPBXOR: return intop(^, v1, v2); - case LUA_OPSHL: return luaV_shiftl(v1, v2); - case LUA_OPSHR: return luaV_shiftl(v1, -v2); - case LUA_OPUNM: return intop(-, 0, v1); - case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1); - default: lua_assert(0); return 0; - } -} - - -static lua_Number numarith (lua_State *L, int op, lua_Number v1, - lua_Number v2) { - switch (op) { - case LUA_OPADD: return luai_numadd(L, v1, v2); - case LUA_OPSUB: return luai_numsub(L, v1, v2); - case LUA_OPMUL: return luai_nummul(L, v1, v2); - case LUA_OPDIV: return luai_numdiv(L, v1, v2); - case LUA_OPPOW: return luai_numpow(L, v1, v2); - case LUA_OPIDIV: return luai_numidiv(L, v1, v2); - case LUA_OPUNM: return luai_numunm(L, v1); - case LUA_OPMOD: return luaV_modf(L, v1, v2); - default: lua_assert(0); return 0; - } -} - - -int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2, - TValue *res) { - switch (op) { - case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: - case LUA_OPSHL: case LUA_OPSHR: - case LUA_OPBNOT: { /* operate only on integers */ - lua_Integer i1; lua_Integer i2; - if (tointegerns(p1, &i1) && tointegerns(p2, &i2)) { - setivalue(res, intarith(L, op, i1, i2)); - return 1; - } - else return 0; /* fail */ - } - case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ - lua_Number n1; lua_Number n2; - if (tonumberns(p1, n1) && tonumberns(p2, n2)) { - setfltvalue(res, numarith(L, op, n1, n2)); - return 1; - } - else return 0; /* fail */ - } - default: { /* other operations */ - lua_Number n1; lua_Number n2; - if (ttisinteger(p1) && ttisinteger(p2)) { - setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); - return 1; - } - else if (tonumberns(p1, n1) && tonumberns(p2, n2)) { - setfltvalue(res, numarith(L, op, n1, n2)); - return 1; - } - else return 0; /* fail */ - } - } -} - - -void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, - StkId res) { - if (!luaO_rawarith(L, op, p1, p2, s2v(res))) { - /* could not perform raw operation; try metamethod */ - 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; -} - - -static int isneg (const char **s) { - if (**s == '-') { (*s)++; return 1; } - else if (**s == '+') (*s)++; - return 0; -} - - - -/* -** {================================================================== -** Lua's implementation for 'lua_strx2number' -** =================================================================== -*/ - -#if !defined(lua_strx2number) - -/* maximum number of significant digits to read (to avoid overflows - even with single floats) */ -#define MAXSIGDIG 30 - -/* -** convert a hexadecimal numeric string to a number, following -** 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 hasdot = 0; /* true after seen a dot */ - *endptr = cast_charp(s); /* nothing is valid yet */ - while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ - neg = isneg(&s); /* check sign */ - 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 == 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)? */ - nosigdig++; - 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 (hasdot) e--; /* decimal digit? correct exponent */ - } - else break; /* neither a dot nor a digit */ - } - if (nosigdig + sigdig == 0) /* no digits? */ - return 0.0; /* invalid format */ - *endptr = cast_charp(s); /* valid up to here */ - e *= 4; /* each digit multiplies/divides value by 2^4 */ - if (*s == 'p' || *s == 'P') { /* exponent part? */ - int exp1 = 0; /* exponent value */ - int neg1; /* exponent sign */ - s++; /* skip 'p' */ - neg1 = isneg(&s); /* sign */ - if (!lisdigit(cast_uchar(*s))) - return 0.0; /* invalid; must have at least one digit */ - while (lisdigit(cast_uchar(*s))) /* read exponent */ - exp1 = exp1 * 10 + *(s++) - '0'; - if (neg1) exp1 = -exp1; - e += exp1; - *endptr = cast_charp(s); /* valid up to here */ - } - if (neg) r = -r; - return l_mathop(ldexp)(r, e); -} - -#endif -/* }====================================================== */ - - -/* maximum length of a numeral to be converted to a number */ -#if !defined (L_MAXLENNUM) -#define L_MAXLENNUM 200 -#endif - -/* -** Convert string 's' to a Lua number (put in 'result'). Return NULL on -** fail or the address of the ending '\0' on success. ('mode' == 'x') -** means a hexadecimal numeral. -*/ -static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { - char *endptr; - *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */ - : lua_str2number(s, &endptr); - if (endptr == s) return NULL; /* nothing recognized? */ - while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */ - return (*endptr == '\0') ? endptr : NULL; /* OK iff no trailing chars */ -} - - -/* -** Convert string 's' to a Lua number (put in 'result') handling the -** current locale. -** This function accepts both the current locale or a dot as the radix -** mark. If the conversion fails, it may mean number has a dot but -** locale accepts something else. In that case, the code copies 's' -** to a buffer (because 's' is read-only), changes the dot to the -** current locale radix mark, and tries to convert again. -** The variable 'mode' checks for special characters in the string: -** - 'n' means 'inf' or 'nan' (which should be rejected) -** - 'x' means a hexadecimal numeral -** - '.' just optimizes the search for the common case (no special chars) -*/ -static const char *l_str2d (const char *s, lua_Number *result) { - const char *endptr; - const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */ - int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; - if (mode == 'n') /* reject 'inf' and 'nan' */ - return NULL; - endptr = l_str2dloc(s, result, mode); /* try to convert */ - if (endptr == NULL) { /* failed? may be a different locale */ - char buff[L_MAXLENNUM + 1]; - const char *pdot = strchr(s, '.'); - if (pdot == NULL || strlen(s) > L_MAXLENNUM) - return NULL; /* string too long or no dot; fail */ - strcpy(buff, s); /* copy string to buffer */ - buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ - endptr = l_str2dloc(buff, result, mode); /* try again */ - if (endptr != NULL) - endptr = s + (endptr - buff); /* make relative to 's' */ - } - return endptr; -} - - -#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10) -#define MAXLASTD cast_int(LUA_MAXINTEGER % 10) - -static const char *l_str2int (const char *s, lua_Integer *result) { - lua_Unsigned a = 0; - int empty = 1; - int neg; - while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ - neg = isneg(&s); - if (s[0] == '0' && - (s[1] == 'x' || s[1] == 'X')) { /* hex? */ - s += 2; /* skip '0x' */ - for (; lisxdigit(cast_uchar(*s)); s++) { - a = a * 16 + luaO_hexavalue(*s); - empty = 0; - } - } - else { /* decimal */ - for (; lisdigit(cast_uchar(*s)); s++) { - int d = *s - '0'; - if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ - return NULL; /* do not accept it (as integer) */ - a = a * 10 + d; - empty = 0; - } - } - while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ - if (empty || *s != '\0') return NULL; /* something wrong in the numeral */ - else { - *result = l_castU2S((neg) ? 0u - a : a); - return s; - } -} - - -size_t luaO_str2num (const char *s, TValue *o) { - lua_Integer i; lua_Number n; - const char *e; - if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */ - setivalue(o, i); - } - else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */ - setfltvalue(o, n); - } - else - return 0; /* conversion failed */ - return (e - s) + 1; /* success; return string size */ -} - - -int luaO_utf8esc (char *buff, unsigned long x) { - int n = 1; /* number of bytes put in buffer (backwards) */ - lua_assert(x <= 0x7FFFFFFFu); - if (x < 0x80) /* ascii? */ - buff[UTF8BUFFSZ - 1] = cast_char(x); - else { /* need continuation bytes */ - unsigned int mfb = 0x3f; /* maximum that fits in first byte */ - do { /* add continuation bytes */ - buff[UTF8BUFFSZ - (n++)] = cast_char(0x80 | (x & 0x3f)); - x >>= 6; /* remove added bits */ - mfb >>= 1; /* now there is one less bit available in first byte */ - } while (x > mfb); /* still needs continuation byte? */ - buff[UTF8BUFFSZ - n] = cast_char((~mfb << 1) | x); /* add first byte */ - } - return n; -} - - -/* -** Maximum length of the conversion of a number to a string. Must be -** enough to accommodate both LUA_INTEGER_FMT and LUA_NUMBER_FMT. -** (For a long long int, this is 19 digits plus a sign and a final '\0', -** adding to 21. For a long double, it can go to a sign, 33 digits, -** the dot, an exponent letter, an exponent sign, 5 exponent digits, -** and a final '\0', adding to 43.) -*/ -#define MAXNUMBER2STR 44 - - -/* -** Convert a number object to a string, adding it to a buffer -*/ -static int tostringbuff (TValue *obj, char *buff) { - int len; - lua_assert(ttisnumber(obj)); - if (ttisinteger(obj)) - len = lua_integer2str(buff, MAXNUMBER2STR, ivalue(obj)); - else { - len = lua_number2str(buff, MAXNUMBER2STR, fltvalue(obj)); - if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ - buff[len++] = lua_getlocaledecpoint(); - buff[len++] = '0'; /* adds '.0' to result */ - } - } - return len; -} - - -/* -** Convert a number object to a Lua string, replacing the value at 'obj' -*/ -void luaO_tostring (lua_State *L, TValue *obj) { - char buff[MAXNUMBER2STR]; - int len = tostringbuff(obj, buff); - setsvalue(L, obj, luaS_newlstr(L, buff, len)); -} - - - - -/* -** {================================================================== -** 'luaO_pushvfstring' -** =================================================================== -*/ - -/* size for buffer space used by 'luaO_pushvfstring' */ -#define BUFVFS 200 - -/* buffer used by 'luaO_pushvfstring' */ -typedef struct BuffFS { - lua_State *L; - int pushed; /* number of string pieces already on the stack */ - int blen; /* length of partial string in 'space' */ - char space[BUFVFS]; /* holds last part of the result */ -} BuffFS; - - -/* -** Push given string to the stack, as part of the buffer, and -** join the partial strings in the stack into one. -*/ -static void pushstr (BuffFS *buff, const char *str, size_t l) { - lua_State *L = buff->L; - setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); - L->top++; /* may use one extra slot */ - buff->pushed++; - luaV_concat(L, buff->pushed); /* join partial results into one */ - buff->pushed = 1; -} - - -/* -** empty the buffer space into the stack -*/ -static void clearbuff (BuffFS *buff) { - pushstr(buff, buff->space, buff->blen); /* push buffer contents */ - buff->blen = 0; /* space now is empty */ -} - - -/* -** Get a space of size 'sz' in the buffer. If buffer has not enough -** space, empty it. 'sz' must fit in an empty buffer. -*/ -static char *getbuff (BuffFS *buff, int sz) { - lua_assert(buff->blen <= BUFVFS); lua_assert(sz <= BUFVFS); - if (sz > BUFVFS - buff->blen) /* not enough space? */ - clearbuff(buff); - return buff->space + buff->blen; -} - - -#define addsize(b,sz) ((b)->blen += (sz)) - - -/* -** Add 'str' to the buffer. If string is larger than the buffer space, -** push the string directly to the stack. -*/ -static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { - if (slen <= BUFVFS) { /* does string fit into buffer? */ - char *bf = getbuff(buff, cast_int(slen)); - memcpy(bf, str, slen); /* add string to buffer */ - addsize(buff, cast_int(slen)); - } - else { /* string larger than buffer */ - clearbuff(buff); /* string comes after buffer's content */ - pushstr(buff, str, slen); /* push string */ - } -} - - -/* -** Add a number to the buffer. -*/ -static void addnum2buff (BuffFS *buff, TValue *num) { - char *numbuff = getbuff(buff, MAXNUMBER2STR); - int len = tostringbuff(num, numbuff); /* format number into 'numbuff' */ - addsize(buff, len); -} - - -/* -** this function handles only '%d', '%c', '%f', '%p', '%s', and '%%' - conventional formats, plus Lua-specific '%I' and '%U' -*/ -const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { - BuffFS buff; /* holds last part of the result */ - const char *e; /* points to next '%' */ - buff.pushed = buff.blen = 0; - buff.L = L; - while ((e = strchr(fmt, '%')) != NULL) { - addstr2buff(&buff, fmt, e - fmt); /* add 'fmt' up to '%' */ - switch (*(e + 1)) { /* conversion specifier */ - case 's': { /* zero-terminated string */ - const char *s = va_arg(argp, char *); - if (s == NULL) s = "(null)"; - addstr2buff(&buff, s, strlen(s)); - break; - } - case 'c': { /* an 'int' as a character */ - char c = cast_uchar(va_arg(argp, int)); - addstr2buff(&buff, &c, sizeof(char)); - break; - } - case 'd': { /* an 'int' */ - TValue num; - setivalue(&num, va_arg(argp, int)); - addnum2buff(&buff, &num); - break; - } - case 'I': { /* a 'lua_Integer' */ - TValue num; - setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt))); - addnum2buff(&buff, &num); - break; - } - case 'f': { /* a 'lua_Number' */ - TValue num; - setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber))); - addnum2buff(&buff, &num); - break; - } - case 'p': { /* a pointer */ - const int sz = 3 * sizeof(void*) + 8; /* enough space for '%p' */ - char *bf = getbuff(&buff, sz); - void *p = va_arg(argp, void *); - int len = lua_pointer2str(bf, sz, p); - addsize(&buff, len); - break; - } - case 'U': { /* a 'long' as a UTF-8 sequence */ - char bf[UTF8BUFFSZ]; - int len = luaO_utf8esc(bf, va_arg(argp, long)); - addstr2buff(&buff, bf + UTF8BUFFSZ - len, len); - break; - } - case '%': { - addstr2buff(&buff, "%", 1); - break; - } - default: { - luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'", - *(e + 1)); - } - } - fmt = e + 2; /* skip '%' and the specifier */ - } - addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ - clearbuff(&buff); /* empty buffer into the stack */ - lua_assert(buff.pushed == 1); - return svalue(s2v(L->top - 1)); -} - - -const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { - const char *msg; - va_list argp; - va_start(argp, fmt); - msg = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - return msg; -} - -/* }================================================================== */ - - -#define RETS "..." -#define PRE "[string \"" -#define POS "\"]" - -#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) - -void luaO_chunkid (char *out, const char *source, size_t srclen) { - size_t bufflen = LUA_IDSIZE; /* free space in buffer */ - if (*source == '=') { /* 'literal' source */ - if (srclen <= bufflen) /* small enough? */ - memcpy(out, source + 1, srclen * sizeof(char)); - else { /* truncate it */ - addstr(out, source + 1, bufflen - 1); - *out = '\0'; - } - } - else if (*source == '@') { /* file name */ - if (srclen <= bufflen) /* small enough? */ - memcpy(out, source + 1, srclen * sizeof(char)); - else { /* add '...' before rest of name */ - addstr(out, RETS, LL(RETS)); - bufflen -= LL(RETS); - memcpy(out, source + 1 + srclen - bufflen, bufflen * sizeof(char)); - } - } - else { /* string; format as [string "source"] */ - const char *nl = strchr(source, '\n'); /* find first new line (if any) */ - addstr(out, PRE, LL(PRE)); /* add prefix */ - bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ - if (srclen < bufflen && nl == NULL) { /* small one-line source? */ - addstr(out, source, srclen); /* keep it */ - } - else { - if (nl != NULL) srclen = nl - source; /* stop at first newline */ - if (srclen > bufflen) srclen = bufflen; - addstr(out, source, srclen); - addstr(out, RETS, LL(RETS)); - } - memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); - } -} - diff --git a/source/external/lua/lobject.h b/source/external/lua/lobject.h index 950bebb..156c942 100644 --- a/source/external/lua/lobject.h +++ b/source/external/lua/lobject.h @@ -52,6 +52,8 @@ typedef union Value { lua_CFunction f; /* light C functions */ lua_Integer i; /* integer numbers */ lua_Number n; /* float numbers */ + /* not used, but may avoid warnings for uninitialized value */ + lu_byte ub; } Value; @@ -68,7 +70,7 @@ typedef struct TValue { #define val_(o) ((o)->value_) -#define valraw(o) (&val_(o)) +#define valraw(o) (val_(o)) /* raw type tag of a TValue */ @@ -112,7 +114,7 @@ typedef struct TValue { #define settt_(o,t) ((o)->tt_=(t)) -/* main macro to copy values (from 'obj1' to 'obj2') */ +/* main macro to copy values (from 'obj2' to 'obj1') */ #define setobj(L,obj1,obj2) \ { TValue *io1=(obj1); const TValue *io2=(obj2); \ io1->value_ = io2->value_; settt_(io1, io2->tt_); \ @@ -155,6 +157,17 @@ typedef union StackValue { /* index to stack elements */ typedef StackValue *StkId; + +/* +** When reallocating the stack, change all pointers to the stack into +** proper offsets. +*/ +typedef union { + StkId p; /* actual pointer */ + ptrdiff_t offset; /* used while the stack is being reallocated */ +} StkIdRel; + + /* convert a 'StackValue' to a 'TValue' */ #define s2v(o) (&(o)->val) @@ -175,10 +188,21 @@ typedef StackValue *StkId; /* Value returned for a key not found in a table (absent key) */ #define LUA_VABSTKEY makevariant(LUA_TNIL, 2) +/* Special variant to signal that a fast get is accessing a non-table */ +#define LUA_VNOTABLE makevariant(LUA_TNIL, 3) + /* macro to test for (any kind of) nil */ #define ttisnil(v) checktype((v), LUA_TNIL) +/* +** Macro to test the result of a table access. Formally, it should +** distinguish between LUA_VEMPTY/LUA_VABSTKEY/LUA_VNOTABLE and +** other tags. As currently nil is equivalent to LUA_VEMPTY, it is +** simpler to just test whether the value is nil. +*/ +#define tagisempty(tag) (novariant(tag) == LUA_TNIL) + /* macro to test for a standard nil */ #define ttisstrictnil(o) checktag((o), LUA_VNIL) @@ -232,6 +256,8 @@ typedef StackValue *StkId; #define l_isfalse(o) (ttisfalse(o) || ttisnil(o)) +#define tagisfalse(t) ((t) == LUA_VFALSE || novariant(t) == LUA_TNIL) + #define setbfvalue(obj) settt_(obj, LUA_VFALSE) @@ -367,37 +393,54 @@ typedef struct GCObject { #define setsvalue2n setsvalue +/* Kinds of long strings (stored in 'shrlen') */ +#define LSTRREG -1 /* regular long string */ +#define LSTRFIX -2 /* fixed external long string */ +#define LSTRMEM -3 /* external long string with deallocation */ + + /* ** Header for a string value. */ typedef struct TString { CommonHeader; lu_byte extra; /* reserved words for short strings; "has hash" for longs */ - lu_byte shrlen; /* length for short strings */ + ls_byte shrlen; /* length for short strings, negative for long strings */ unsigned int hash; union { size_t lnglen; /* length for long strings */ struct TString *hnext; /* linked list for hash table */ } u; - char contents[1]; + char *contents; /* pointer to content in long strings */ + lua_Alloc falloc; /* deallocation function for external strings */ + void *ud; /* user data for external strings */ } TString; +#define strisshr(ts) ((ts)->shrlen >= 0) +#define isextstr(ts) (ttislngstring(ts) && tsvalue(ts)->shrlen != LSTRREG) + /* -** Get the actual string (array of bytes) from a 'TString'. +** Get the actual string (array of bytes) from a 'TString'. (Generic +** version and specialized versions for long and short strings.) */ -#define getstr(ts) ((ts)->contents) +#define rawgetshrstr(ts) (cast_charp(&(ts)->contents)) +#define getshrstr(ts) check_exp(strisshr(ts), rawgetshrstr(ts)) +#define getlngstr(ts) check_exp(!strisshr(ts), (ts)->contents) +#define getstr(ts) (strisshr(ts) ? rawgetshrstr(ts) : (ts)->contents) -/* get the actual string (array of bytes) from a Lua value */ -#define svalue(o) getstr(tsvalue(o)) +/* get string length from 'TString *ts' */ +#define tsslen(ts) \ + (strisshr(ts) ? cast_sizet((ts)->shrlen) : (ts)->u.lnglen) -/* get string length from 'TString *s' */ -#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen) - -/* get string length from 'TValue *o' */ -#define vslen(o) tsslen(tsvalue(o)) +/* +** Get string and length */ +#define getlstr(ts, len) \ + (strisshr(ts) \ + ? (cast_void((len) = cast_sizet((ts)->shrlen)), rawgetshrstr(ts)) \ + : (cast_void((len) = (ts)->u.lnglen), (ts)->contents)) /* }================================================================== */ @@ -475,8 +518,8 @@ typedef struct Udata0 { /* compute the offset of the memory area of a userdata */ #define udatamemoffset(nuv) \ - ((nuv) == 0 ? offsetof(Udata0, bindata) \ - : offsetof(Udata, uv) + (sizeof(UValue) * (nuv))) + ((nuv) == 0 ? offsetof(Udata0, bindata) \ + : offsetof(Udata, uv) + (sizeof(UValue) * (nuv))) /* get the address of the memory block inside 'Udata' */ #define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) @@ -496,6 +539,9 @@ typedef struct Udata0 { #define LUA_VPROTO makevariant(LUA_TPROTO, 0) +typedef l_uint32 Instruction; + + /* ** Description of an upvalue for function prototypes */ @@ -533,13 +579,30 @@ typedef struct AbsLineInfo { int line; } AbsLineInfo; + +/* +** Flags in Prototypes +*/ +#define PF_VAHID 1 /* function has hidden vararg arguments */ +#define PF_VATAB 2 /* function has vararg table */ +#define PF_FIXED 4 /* prototype has parts in fixed memory */ + +/* a vararg function either has hidden args. or a vararg table */ +#define isvararg(p) ((p)->flag & (PF_VAHID | PF_VATAB)) + +/* +** mark that a function needs a vararg table. (The flag PF_VAHID will +** be cleared later.) +*/ +#define needvatab(p) ((p)->flag |= PF_VATAB) + /* ** Function Prototypes */ typedef struct Proto { CommonHeader; lu_byte numparams; /* number of fixed (named) parameters */ - lu_byte is_vararg; + lu_byte flag; lu_byte maxstacksize; /* number of registers needed by this function */ int sizeupvalues; /* size of 'upvalues' */ int sizek; /* size of 'k' */ @@ -615,8 +678,10 @@ typedef struct Proto { */ typedef struct UpVal { CommonHeader; - lu_byte tbc; /* true if it represents a to-be-closed variable */ - TValue *v; /* points to stack or to its own value */ + union { + TValue *p; /* points to stack or to its own value */ + ptrdiff_t offset; /* used while the stack is being reallocated */ + } v; union { struct { /* (when open) */ struct UpVal *next; /* linked list */ @@ -695,10 +760,9 @@ typedef union Node { /* copy a value into a key */ -#define setnodekey(L,node,obj) \ +#define setnodekey(node,obj) \ { Node *n_=(node); const TValue *io_=(obj); \ - n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \ - checkliveness(L,io_); } + n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; } /* copy a value from a key */ @@ -708,27 +772,14 @@ typedef union Node { checkliveness(L,io_); } -/* -** About 'alimit': if 'isrealasize(t)' is true, then 'alimit' is the -** real size of 'array'. Otherwise, the real size of 'array' is the -** smallest power of two not smaller than 'alimit' (or zero iff 'alimit' -** is zero); 'alimit' is then used as a hint for #t. -*/ - -#define BITRAS (1 << 7) -#define isrealasize(t) (!((t)->flags & BITRAS)) -#define setrealasize(t) ((t)->flags &= cast_byte(~BITRAS)) -#define setnorealasize(t) ((t)->flags |= BITRAS) - typedef struct Table { CommonHeader; lu_byte flags; /* 1<

lsizenode)) /* size of buffer for 'luaO_utf8esc' function */ #define UTF8BUFFSZ 8 -LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); -LUAI_FUNC int luaO_ceillog2 (unsigned int x); + +/* macro to call 'luaO_pushvfstring' correctly */ +#define pushvfstring(L, argp, fmt, msg) \ + { va_start(argp, fmt); \ + msg = luaO_pushvfstring(L, fmt, argp); \ + va_end(argp); \ + if (msg == NULL) luaD_throw(L, LUA_ERRMEM); /* only after 'va_end' */ } + + +LUAI_FUNC int luaO_utf8esc (char *buff, l_uint32 x); +LUAI_FUNC lu_byte luaO_ceillog2 (unsigned int x); +LUAI_FUNC lu_byte luaO_codeparam (unsigned int p); +LUAI_FUNC l_mem luaO_applyparam (lu_byte p, l_mem x); + LUAI_FUNC int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2, TValue *res); LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, StkId res); LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); -LUAI_FUNC int luaO_hexavalue (int c); +LUAI_FUNC unsigned luaO_tostringbuff (const TValue *obj, char *buff); +LUAI_FUNC lu_byte luaO_hexavalue (int c); LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj); LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp); diff --git a/source/external/lua/lopcodes.c b/source/external/lua/lopcodes.c deleted file mode 100644 index c67aa22..0000000 --- a/source/external/lua/lopcodes.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -** $Id: lopcodes.c $ -** Opcodes for Lua virtual machine -** See Copyright Notice in lua.h -*/ - -#define lopcodes_c -#define LUA_CORE - -#include "lprefix.h" - - -#include "lopcodes.h" - - -/* ORDER OP */ - -LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { -/* MM OT IT T A mode opcode */ - opmode(0, 0, 0, 0, 1, iABC) /* OP_MOVE */ - ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADI */ - ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ - ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ - ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LFALSESKIP */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABUP */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABLE */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETI */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETFIELD */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABUP */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BANDK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BORK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXORK */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHRI */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHLI */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADD */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUB */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MUL */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MOD */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POW */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIV */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIV */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BAND */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BOR */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXOR */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHL */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHR */ - ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBIN */ - ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINI*/ - ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINK*/ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_UNM */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BNOT */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NOT */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LEN */ - ,opmode(0, 0, 0, 0, 1, iABC) /* OP_CONCAT */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TBC */ - ,opmode(0, 0, 0, 0, 0, isJ) /* OP_JMP */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQ */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LT */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LE */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQK */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQI */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LTI */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LEI */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GTI */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GEI */ - ,opmode(0, 0, 0, 1, 0, iABC) /* OP_TEST */ - ,opmode(0, 0, 0, 1, 1, iABC) /* OP_TESTSET */ - ,opmode(0, 1, 1, 0, 1, iABC) /* OP_CALL */ - ,opmode(0, 1, 1, 0, 1, iABC) /* OP_TAILCALL */ - ,opmode(0, 0, 1, 0, 0, iABC) /* OP_RETURN */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN0 */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN1 */ - ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORLOOP */ - ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORPREP */ - ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ - ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ - ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ - ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ - ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ - ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ - ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ -}; - diff --git a/source/external/lua/lopcodes.h b/source/external/lua/lopcodes.h index d6a47e5..b6bd182 100644 --- a/source/external/lua/lopcodes.h +++ b/source/external/lua/lopcodes.h @@ -8,6 +8,7 @@ #define lopcodes_h #include "llimits.h" +#include "lobject.h" /*=========================================================================== @@ -18,25 +19,30 @@ 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 iABC C(8) | B(8) |k| A(8) | Op(7) | +ivABC vC(10) | vB(6) |k| A(8) | Op(7) | iABx Bx(17) | A(8) | Op(7) | iAsBx sBx (signed)(17) | A(8) | Op(7) | iAx Ax(25) | Op(7) | -isJ sJ(25) | Op(7) | +isJ sJ (signed)(25) | Op(7) | - A signed argument is represented in excess K: the represented value is - the written unsigned value minus K, where K is half the maximum for the - corresponding unsigned argument. + ('v' stands for "variant", 's' for "signed", 'x' for "extended".) + A signed argument is represented in excess K: The represented value is + the written unsigned value minus K, where K is half (rounded down) the + maximum value for the corresponding unsigned argument. ===========================================================================*/ -enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ +/* basic instruction formats */ +enum OpMode {iABC, ivABC, iABx, iAsBx, iAx, isJ}; /* ** size and position of opcode arguments. */ #define SIZE_C 8 +#define SIZE_vC 10 #define SIZE_B 8 +#define SIZE_vB 6 #define SIZE_Bx (SIZE_C + SIZE_B + 1) #define SIZE_A 8 #define SIZE_Ax (SIZE_Bx + SIZE_A) @@ -49,7 +55,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ #define POS_A (POS_OP + SIZE_OP) #define POS_k (POS_A + SIZE_A) #define POS_B (POS_k + 1) +#define POS_vB (POS_k + 1) #define POS_C (POS_B + SIZE_B) +#define POS_vC (POS_vB + SIZE_vB) #define POS_Bx POS_k @@ -64,14 +72,17 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ ** so they must fit in ints. */ -/* Check whether type 'int' has at least 'b' bits ('b' < 32) */ -#define L_INTHASBITS(b) ((UINT_MAX >> ((b) - 1)) >= 1) +/* +** Check whether type 'int' has at least 'b' + 1 bits. +** 'b' < 32; +1 for the sign bit. +*/ +#define L_INTHASBITS(b) ((UINT_MAX >> (b)) >= 1) #if L_INTHASBITS(SIZE_Bx) #define MAXARG_Bx ((1<>1) /* 'sBx' is signed */ @@ -80,13 +91,13 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ #if L_INTHASBITS(SIZE_Ax) #define MAXARG_Ax ((1<> 1) @@ -94,7 +105,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ #define MAXARG_A ((1<> 1) #define int2sC(i) ((i) + OFFSET_sC) @@ -113,28 +126,36 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ #define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ - ((cast(Instruction, o)<>(pos)) & MASK1(size,0))) #define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ - ((cast(Instruction, v)<> sC */ OP_SHLI,/* A B sC R[A] := sC << R[B] */ +OP_SHRI,/* A B sC R[A] := R[B] >> sC */ OP_ADD,/* A B C R[A] := R[B] + R[C] */ OP_SUB,/* A B C R[A] := R[B] - R[C] */ @@ -280,12 +315,12 @@ OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */ OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */ OP_TEST,/* A k if (not R[A] == k) then pc++ */ -OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */ +OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */ OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */ OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */ -OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */ +OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] */ OP_RETURN0,/* return */ OP_RETURN1,/* A return R[A] */ @@ -297,13 +332,17 @@ OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */ OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ -OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ +OP_SETLIST,/* A vB vC k R[A][vC+i] := R[A+i], 1 <= i <= vB */ OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ -OP_VARARG,/* A C R[A], R[A+1], ..., R[A+C-2] = vararg */ +OP_VARARG,/* A B C k R[A], ..., R[A+C-2] = varargs */ -OP_VARARGPREP,/*A (adjust vararg parameters) */ +OP_GETVARG, /* A B C R[A] := R[B][R[C]], R[B] is vararg parameter */ + +OP_ERRNNIL,/* A Bx raise error if R[A] ~= nil (K[Bx - 1] is global name)*/ + +OP_VARARGPREP,/* (adjust varargs) */ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ } OpCode; @@ -315,12 +354,25 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ /*=========================================================================== Notes: + + (*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean + value, in a code equivalent to (not cond ? false : true). (It + produces false and skips the next instruction producing true.) + + (*) Opcodes OP_MMBIN and variants follow each arithmetic and + bitwise opcode. If the operation succeeds, it skips this next + opcode. Otherwise, this opcode calls the corresponding metamethod. + + (*) Opcode OP_TESTSET is used in short-circuit expressions that need + both to jump and to produce a value, such as (a = b or c). + (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then 'top' is set to last_result+1, so next open instruction (OP_CALL, OP_RETURN*, OP_SETLIST) may use 'top'. (*) In OP_VARARG, if (C == 0) then use actual number of varargs and - set top (like in OP_CALL with C == 0). + set top (like in OP_CALL with C == 0). 'k' means function has a + vararg table, which is in R[B]. (*) In OP_RETURN, if (B == 0) then return up to 'top'. @@ -331,22 +383,27 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the bits of C). - (*) In OP_NEWTABLE, B is log2 of the hash size (which is always a + (*) In OP_NEWTABLE, vB is log2 of the hash size (which is always a power of 2) plus 1, or zero for size zero. If not k, the array size - is C. Otherwise, the array size is EXTRAARG _ C. + is vC. Otherwise, the array size is EXTRAARG _ vC. + + (*) In OP_ERRNNIL, (Bx == 0) means index of global name doesn't + fit in Bx. (So, that name is not available for the error message.) (*) For comparisons, k specifies what condition the test should accept (true or false). (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped - (the constant is the first operand). + (the constant is the first operand). - (*) All 'skips' (pc++) assume that next instruction is a jump. + (*) All comparison and test instructions assume that the instruction + being skipped (pc++) is a jump. (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the function builds upvalues, which may need to be closed. C > 0 means - the function is vararg, so that its 'func' must be corrected before - returning; in this case, (C - 1) is its number of fixed parameters. + the function has hidden vararg arguments, so that its 'func' must be + corrected before returning; in this case, (C - 1) is its number of + fixed parameters. (*) In comparisons with an immediate operand, C signals whether the original operand was a float. (It must be corrected in case of @@ -374,19 +431,9 @@ LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];) #define testOTMode(m) (luaP_opmodes[m] & (1 << 6)) #define testMMMode(m) (luaP_opmodes[m] & (1 << 7)) -/* "out top" (set top for next instruction) */ -#define isOT(i) \ - ((testOTMode(GET_OPCODE(i)) && GETARG_C(i) == 0) || \ - GET_OPCODE(i) == OP_TAILCALL) -/* "in top" (uses top from previous instruction) */ -#define isIT(i) (testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0) +LUAI_FUNC int luaP_isOT (Instruction i); +LUAI_FUNC int luaP_isIT (Instruction i); -#define opmode(mm,ot,it,t,a,m) \ - (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m)) - - -/* number of list items to accumulate before a SETLIST instruction */ -#define LFIELDS_PER_FLUSH 50 #endif diff --git a/source/external/lua/lopnames.h b/source/external/lua/lopnames.h index 965cec9..0554a2e 100644 --- a/source/external/lua/lopnames.h +++ b/source/external/lua/lopnames.h @@ -45,8 +45,8 @@ static const char *const opnames[] = { "BANDK", "BORK", "BXORK", - "SHRI", "SHLI", + "SHRI", "ADD", "SUB", "MUL", @@ -94,6 +94,8 @@ static const char *const opnames[] = { "SETLIST", "CLOSURE", "VARARG", + "GETVARG", + "ERRNNIL", "VARARGPREP", "EXTRAARG", NULL diff --git a/source/external/lua/loslib.c b/source/external/lua/loslib.c deleted file mode 100644 index 3e20d62..0000000 --- a/source/external/lua/loslib.c +++ /dev/null @@ -1,430 +0,0 @@ -/* -** $Id: loslib.c $ -** Standard Operating System library -** See Copyright Notice in lua.h -*/ - -#define loslib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* -** {================================================================== -** List of valid conversion specifiers for the 'strftime' function; -** options are grouped by length; group of length 2 start with '||'. -** =================================================================== -*/ -#if !defined(LUA_STRFTIMEOPTIONS) /* { */ - -/* options for ANSI C 89 (only 1-char options) */ -#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%" - -/* options for ISO C 99 and POSIX */ -#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ - "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */ - -/* options for Windows */ -#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \ - "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */ - -#if defined(LUA_USE_WINDOWS) -#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN -#elif defined(LUA_USE_C89) -#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89 -#else /* C99 specification */ -#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99 -#endif - -#endif /* } */ -/* }================================================================== */ - - -/* -** {================================================================== -** Configuration for time-related stuff -** =================================================================== -*/ - -/* -** type to represent time_t in Lua -*/ -#if !defined(LUA_NUMTIME) /* { */ - -#define l_timet lua_Integer -#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) -#define l_gettime(L,arg) luaL_checkinteger(L, arg) - -#else /* }{ */ - -#define l_timet lua_Number -#define l_pushtime(L,t) lua_pushnumber(L,(lua_Number)(t)) -#define l_gettime(L,arg) luaL_checknumber(L, arg) - -#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 /* } */ - -/* }================================================================== */ - - -/* -** {================================================================== -** 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 - -#if !defined(LUA_TMPNAMTEMPLATE) -#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX" -#endif - -#define lua_tmpnam(b,e) { \ - strcpy(b, LUA_TMPNAMTEMPLATE); \ - e = mkstemp(b); \ - if (e != -1) close(e); \ - e = (e == -1); } - -#else /* }{ */ - -/* ISO C definitions */ -#define LUA_TMPNAMBUFSIZE L_tmpnam -#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } - -#endif /* } */ - -#endif /* } */ -/* }================================================================== */ - - - -static int os_execute (lua_State *L) { - const char *cmd = luaL_optstring(L, 1, NULL); - int stat; - errno = 0; - stat = system(cmd); - if (cmd != NULL) - return luaL_execresult(L, stat); - else { - lua_pushboolean(L, stat); /* true if there is a shell */ - return 1; - } -} - - -static int os_remove (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - return luaL_fileresult(L, remove(filename) == 0, filename); -} - - -static int os_rename (lua_State *L) { - const char *fromname = luaL_checkstring(L, 1); - const char *toname = luaL_checkstring(L, 2); - return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); -} - - -static int os_tmpname (lua_State *L) { - char buff[LUA_TMPNAMBUFSIZE]; - int err; - lua_tmpnam(buff, err); - if (l_unlikely(err)) - return luaL_error(L, "unable to generate a unique filename"); - lua_pushstring(L, buff); - return 1; -} - - -static int os_getenv (lua_State *L) { - lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ - return 1; -} - - -static int os_clock (lua_State *L) { - lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); - return 1; -} - - -/* -** {====================================================== -** Time/Date operations -** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, -** wday=%w+1, yday=%j, isdst=? } -** ======================================================= -*/ - -/* -** About the overflow check: an overflow cannot occur when time -** is represented by a lua_Integer, because either lua_Integer is -** large enough to represent all int fields or it is not large enough -** to represent a time that cause a field to overflow. However, if -** times are represented as doubles and lua_Integer is int, then the -** time 0x1.e1853b0d184f6p+55 would cause an overflow when adding 1900 -** to compute the year. -*/ -static void setfield (lua_State *L, const char *key, int value, int delta) { - #if (defined(LUA_NUMTIME) && LUA_MAXINTEGER <= INT_MAX) - if (l_unlikely(value > LUA_MAXINTEGER - delta)) - luaL_error(L, "field '%s' is out-of-bound", key); - #endif - lua_pushinteger(L, (lua_Integer)value + delta); - lua_setfield(L, -2, key); -} - - -static void setboolfield (lua_State *L, const char *key, int value) { - if (value < 0) /* undefined? */ - return; /* does not set field */ - lua_pushboolean(L, value); - lua_setfield(L, -2, key); -} - - -/* -** Set all fields from structure 'tm' in the table on top of the stack -*/ -static void setallfields (lua_State *L, struct tm *stm) { - setfield(L, "year", stm->tm_year, 1900); - setfield(L, "month", stm->tm_mon, 1); - setfield(L, "day", stm->tm_mday, 0); - setfield(L, "hour", stm->tm_hour, 0); - setfield(L, "min", stm->tm_min, 0); - setfield(L, "sec", stm->tm_sec, 0); - setfield(L, "yday", stm->tm_yday, 1); - setfield(L, "wday", stm->tm_wday, 1); - setboolfield(L, "isdst", stm->tm_isdst); -} - - -static int getboolfield (lua_State *L, const char *key) { - int res; - res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); - lua_pop(L, 1); - return res; -} - - -static int getfield (lua_State *L, const char *key, int d, int delta) { - int isnum; - int t = lua_getfield(L, -1, key); /* get field and its type */ - lua_Integer res = lua_tointegerx(L, -1, &isnum); - if (!isnum) { /* field is not an integer? */ - if (l_unlikely(t != LUA_TNIL)) /* some other value? */ - return luaL_error(L, "field '%s' is not an integer", key); - else if (l_unlikely(d < 0)) /* absent field; no default? */ - return luaL_error(L, "field '%s' missing in date table", key); - res = d; - } - else { - /* unsigned avoids overflow when lua_Integer has 32 bits */ - if (!(res >= 0 ? (lua_Unsigned)res <= (lua_Unsigned)INT_MAX + delta - : (lua_Integer)INT_MIN + delta <= res)) - return luaL_error(L, "field '%s' is out-of-bound", key); - res -= delta; - } - lua_pop(L, 1); - return (int)res; -} - - -static const char *checkoption (lua_State *L, const char *conv, - ptrdiff_t convlen, char *buff) { - const char *option = LUA_STRFTIMEOPTIONS; - int oplen = 1; /* length of options being checked */ - for (; *option != '\0' && oplen <= convlen; option += oplen) { - if (*option == '|') /* next block? */ - oplen++; /* will check options with next length (+1) */ - else if (memcmp(conv, option, oplen) == 0) { /* match? */ - memcpy(buff, conv, oplen); /* copy valid option to buffer */ - buff[oplen] = '\0'; - return conv + oplen; /* return next item */ - } - } - luaL_argerror(L, 1, - lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); - return conv; /* to avoid warnings */ -} - - -static time_t l_checktime (lua_State *L, int arg) { - l_timet t = l_gettime(L, arg); - luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); - return (time_t)t; -} - - -/* maximum size for an individual 'strftime' item */ -#define SIZETIMEFMT 250 - - -static int os_date (lua_State *L) { - size_t slen; - const char *s = luaL_optlstring(L, 1, "%c", &slen); - time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); - const char *se = s + slen; /* 's' end */ - struct tm tmr, *stm; - if (*s == '!') { /* UTC? */ - stm = l_gmtime(&t, &tmr); - s++; /* skip '!' */ - } - else - stm = l_localtime(&t, &tmr); - if (stm == NULL) /* invalid date? */ - return luaL_error(L, - "date result cannot be represented in this installation"); - if (strcmp(s, "*t") == 0) { - lua_createtable(L, 0, 9); /* 9 = number of fields */ - setallfields(L, stm); - } - else { - char cc[4]; /* buffer for individual conversion specifiers */ - luaL_Buffer b; - cc[0] = '%'; - luaL_buffinit(L, &b); - while (s < se) { - if (*s != '%') /* not a conversion specifier? */ - luaL_addchar(&b, *s++); - else { - size_t reslen; - char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); - s++; /* skip '%' */ - s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ - reslen = strftime(buff, SIZETIMEFMT, cc, stm); - luaL_addsize(&b, reslen); - } - } - luaL_pushresult(&b); - } - return 1; -} - - -static int os_time (lua_State *L) { - time_t t; - if (lua_isnoneornil(L, 1)) /* called without args? */ - t = time(NULL); /* get current time */ - else { - struct tm ts; - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 1); /* make sure table is at the top */ - ts.tm_year = getfield(L, "year", -1, 1900); - ts.tm_mon = getfield(L, "month", -1, 1); - ts.tm_mday = getfield(L, "day", -1, 0); - ts.tm_hour = getfield(L, "hour", 12, 0); - ts.tm_min = getfield(L, "min", 0, 0); - ts.tm_sec = getfield(L, "sec", 0, 0); - ts.tm_isdst = getboolfield(L, "isdst"); - t = mktime(&ts); - setallfields(L, &ts); /* update fields with normalized values */ - } - if (t != (time_t)(l_timet)t || t == (time_t)(-1)) - return luaL_error(L, - "time result cannot be represented in this installation"); - l_pushtime(L, t); - return 1; -} - - -static int os_difftime (lua_State *L) { - time_t t1 = l_checktime(L, 1); - time_t t2 = l_checktime(L, 2); - lua_pushnumber(L, (lua_Number)difftime(t1, t2)); - return 1; -} - -/* }====================================================== */ - - -static int os_setlocale (lua_State *L) { - static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, - LC_NUMERIC, LC_TIME}; - static const char *const catnames[] = {"all", "collate", "ctype", "monetary", - "numeric", "time", NULL}; - const char *l = luaL_optstring(L, 1, NULL); - int op = luaL_checkoption(L, 2, "all", catnames); - lua_pushstring(L, setlocale(cat[op], l)); - return 1; -} - - -static int os_exit (lua_State *L) { - int status; - if (lua_isboolean(L, 1)) - status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); - else - status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS); - if (lua_toboolean(L, 2)) - lua_close(L); - if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ - return 0; -} - - -static const luaL_Reg syslib[] = { - {"clock", os_clock}, - {"date", os_date}, - {"difftime", os_difftime}, - {"execute", os_execute}, - {"exit", os_exit}, - {"getenv", os_getenv}, - {"remove", os_remove}, - {"rename", os_rename}, - {"setlocale", os_setlocale}, - {"time", os_time}, - {"tmpname", os_tmpname}, - {NULL, NULL} -}; - -/* }====================================================== */ - - - -LUAMOD_API int luaopen_os (lua_State *L) { - luaL_newlib(L, syslib); - return 1; -} - diff --git a/source/external/lua/lparser.c b/source/external/lua/lparser.c deleted file mode 100644 index 284ef1f..0000000 --- a/source/external/lua/lparser.c +++ /dev/null @@ -1,1956 +0,0 @@ -/* -** $Id: lparser.c $ -** Lua Parser -** See Copyright Notice in lua.h -*/ - -#define lparser_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include - -#include "lua.h" - -#include "lcode.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "llex.h" -#include "lmem.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lparser.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" - - - -/* maximum number of local variables per function (must be smaller - than 250, due to the bytecode format) */ -#define MAXVARS 200 - - -#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) - - -/* because all strings are unified by the scanner, the parser - can use pointer equality for string equality */ -#define eqstr(a,b) ((a) == (b)) - - -/* -** nodes for block list (list of active blocks) -*/ -typedef struct BlockCnt { - struct BlockCnt *previous; /* chain */ - int firstlabel; /* index of first label in this block */ - int firstgoto; /* index of first pending goto in this block */ - lu_byte nactvar; /* # active locals outside the block */ - lu_byte upval; /* true if some variable in the block is an upvalue */ - lu_byte isloop; /* true if 'block' is a loop */ - lu_byte insidetbc; /* true if inside the scope of a to-be-closed var. */ -} BlockCnt; - - - -/* -** prototypes for recursive non-terminal functions -*/ -static void statement (LexState *ls); -static void expr (LexState *ls, expdesc *v); - - -static l_noret error_expected (LexState *ls, int token) { - luaX_syntaxerror(ls, - luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, 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->linedefined; - const char *where = (line == 0) - ? "main function" - : luaO_pushfstring(L, "function at line %d", line); - msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", - what, limit, where); - luaX_syntaxerror(fs->ls, msg); -} - - -static void checklimit (FuncState *fs, int v, int l, const char *what) { - if (v > l) errorlimit(fs, l, what); -} - - -/* -** Test whether next token is 'c'; if so, skip it. -*/ -static int testnext (LexState *ls, int c) { - if (ls->t.token == c) { - luaX_next(ls); - return 1; - } - else return 0; -} - - -/* -** Check that next token is 'c'. -*/ -static void check (LexState *ls, int c) { - if (ls->t.token != c) - error_expected(ls, c); -} - - -/* -** Check that next token is 'c' and skip it. -*/ -static void checknext (LexState *ls, int c) { - check(ls, c); - luaX_next(ls); -} - - -#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } - - -/* -** Check that next token is 'what' and skip it. In case of error, -** raise an error that the expected 'what' should match a 'who' -** in line 'where' (if that is not the current line). -*/ -static void check_match (LexState *ls, int what, int who, int where) { - if (l_unlikely(!testnext(ls, what))) { - if (where == ls->linenumber) /* all in the same line? */ - error_expected(ls, what); /* do not need a complex message */ - else { - luaX_syntaxerror(ls, luaO_pushfstring(ls->L, - "%s expected (to close %s at line %d)", - luaX_token2str(ls, what), luaX_token2str(ls, who), where)); - } - } -} - - -static TString *str_checkname (LexState *ls) { - TString *ts; - check(ls, TK_NAME); - ts = ls->t.seminfo.ts; - luaX_next(ls); - return ts; -} - - -static void init_exp (expdesc *e, expkind k, int i) { - e->f = e->t = NO_JUMP; - e->k = k; - e->u.info = i; -} - - -static void codestring (expdesc *e, TString *s) { - e->f = e->t = NO_JUMP; - e->k = VKSTR; - e->u.strval = s; -} - - -static void codename (LexState *ls, expdesc *e) { - codestring(e, str_checkname(ls)); -} - - -/* -** Register a new local variable in the active 'Proto' (for debug -** information). -*/ -static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) { - Proto *f = fs->f; - int oldsize = f->sizelocvars; - luaM_growvector(ls->L, f->locvars, fs->ndebugvars, f->sizelocvars, - LocVar, SHRT_MAX, "local variables"); - while (oldsize < f->sizelocvars) - f->locvars[oldsize++].varname = NULL; - f->locvars[fs->ndebugvars].varname = varname; - f->locvars[fs->ndebugvars].startpc = fs->pc; - luaC_objbarrier(ls->L, f, varname); - return fs->ndebugvars++; -} - - -/* -** Create a new local variable with the given 'name'. Return its index -** in the function. -*/ -static int new_localvar (LexState *ls, TString *name) { - lua_State *L = ls->L; - FuncState *fs = ls->fs; - Dyndata *dyd = ls->dyd; - Vardesc *var; - checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, - MAXVARS, "local variables"); - luaM_growvector(L, dyd->actvar.arr, dyd->actvar.n + 1, - dyd->actvar.size, Vardesc, USHRT_MAX, "local variables"); - var = &dyd->actvar.arr[dyd->actvar.n++]; - var->vd.kind = VDKREG; /* default */ - var->vd.name = name; - return dyd->actvar.n - 1 - fs->firstlocal; -} - -#define new_localvarliteral(ls,v) \ - new_localvar(ls, \ - luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1)); - - - -/* -** Return the "variable description" (Vardesc) of a given variable. -** (Unless noted otherwise, all variables are referred to by their -** compiler indices.) -*/ -static Vardesc *getlocalvardesc (FuncState *fs, int vidx) { - return &fs->ls->dyd->actvar.arr[fs->firstlocal + vidx]; -} - - -/* -** Convert 'nvar', a compiler index level, to its corresponding -** register. For that, search for the highest variable below that level -** that is in a register and uses its register index ('ridx') plus one. -*/ -static int reglevel (FuncState *fs, int nvar) { - while (nvar-- > 0) { - Vardesc *vd = getlocalvardesc(fs, nvar); /* get previous variable */ - if (vd->vd.kind != RDKCTC) /* is in a register? */ - return vd->vd.ridx + 1; - } - return 0; /* no variables in registers */ -} - - -/* -** Return the number of variables in the register stack for the given -** function. -*/ -int luaY_nvarstack (FuncState *fs) { - return reglevel(fs, fs->nactvar); -} - - -/* -** Get the debug-information entry for current variable 'vidx'. -*/ -static LocVar *localdebuginfo (FuncState *fs, int vidx) { - Vardesc *vd = getlocalvardesc(fs, vidx); - if (vd->vd.kind == RDKCTC) - return NULL; /* no debug info. for constants */ - else { - int idx = vd->vd.pidx; - lua_assert(idx < fs->ndebugvars); - return &fs->f->locvars[idx]; - } -} - - -/* -** Create an expression representing variable 'vidx' -*/ -static void init_var (FuncState *fs, expdesc *e, int vidx) { - e->f = e->t = NO_JUMP; - e->k = VLOCAL; - e->u.var.vidx = vidx; - e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx; -} - - -/* -** Raises an error if variable described by 'e' is read only -*/ -static void check_readonly (LexState *ls, expdesc *e) { - FuncState *fs = ls->fs; - TString *varname = NULL; /* to be set if variable is const */ - switch (e->k) { - case VCONST: { - varname = ls->dyd->actvar.arr[e->u.info].vd.name; - break; - } - case VLOCAL: { - Vardesc *vardesc = getlocalvardesc(fs, e->u.var.vidx); - if (vardesc->vd.kind != VDKREG) /* not a regular variable? */ - varname = vardesc->vd.name; - break; - } - case VUPVAL: { - Upvaldesc *up = &fs->f->upvalues[e->u.info]; - if (up->kind != VDKREG) - varname = up->name; - break; - } - default: - return; /* other cases cannot be read-only */ - } - if (varname) { - const char *msg = luaO_pushfstring(ls->L, - "attempt to assign to const variable '%s'", getstr(varname)); - luaK_semerror(ls, msg); /* error */ - } -} - - -/* -** Start the scope for the last 'nvars' created variables. -*/ -static void adjustlocalvars (LexState *ls, int nvars) { - FuncState *fs = ls->fs; - int reglevel = luaY_nvarstack(fs); - int i; - for (i = 0; i < nvars; i++) { - int vidx = fs->nactvar++; - Vardesc *var = getlocalvardesc(fs, vidx); - var->vd.ridx = reglevel++; - var->vd.pidx = registerlocalvar(ls, fs, var->vd.name); - } -} - - -/* -** Close the scope for all variables up to level 'tolevel'. -** (debug info.) -*/ -static void removevars (FuncState *fs, int tolevel) { - fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); - while (fs->nactvar > tolevel) { - LocVar *var = localdebuginfo(fs, --fs->nactvar); - if (var) /* does it have debug information? */ - var->endpc = fs->pc; - } -} - - -/* -** Search the upvalues of the function 'fs' for one -** with the given 'name'. -*/ -static int searchupvalue (FuncState *fs, TString *name) { - int i; - Upvaldesc *up = fs->f->upvalues; - for (i = 0; i < fs->nups; i++) { - if (eqstr(up[i].name, name)) return i; - } - return -1; /* not found */ -} - - -static Upvaldesc *allocupvalue (FuncState *fs) { - 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, - Upvaldesc, MAXUPVAL, "upvalues"); - while (oldsize < f->sizeupvalues) - f->upvalues[oldsize++].name = NULL; - return &f->upvalues[fs->nups++]; -} - - -static int newupvalue (FuncState *fs, TString *name, expdesc *v) { - Upvaldesc *up = allocupvalue(fs); - FuncState *prev = fs->prev; - if (v->k == VLOCAL) { - up->instack = 1; - up->idx = v->u.var.ridx; - up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind; - lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name)); - } - else { - up->instack = 0; - up->idx = cast_byte(v->u.info); - up->kind = prev->f->upvalues[v->u.info].kind; - lua_assert(eqstr(name, prev->f->upvalues[v->u.info].name)); - } - up->name = name; - luaC_objbarrier(fs->ls->L, fs->f, name); - return fs->nups - 1; -} - - -/* -** Look for an active local variable with the name 'n' in the -** function 'fs'. If found, initialize 'var' with it and return -** its expression kind; otherwise return -1. -*/ -static int searchvar (FuncState *fs, TString *n, expdesc *var) { - int i; - for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { - Vardesc *vd = getlocalvardesc(fs, i); - if (eqstr(n, vd->vd.name)) { /* found? */ - if (vd->vd.kind == RDKCTC) /* compile-time constant? */ - init_exp(var, VCONST, fs->firstlocal + i); - else /* real variable */ - init_var(fs, var, i); - return var->k; - } - } - return -1; /* not found */ -} - - -/* -** Mark block where variable at given level was defined -** (to emit close instructions later). -*/ -static void markupval (FuncState *fs, int level) { - BlockCnt *bl = fs->bl; - while (bl->nactvar > level) - bl = bl->previous; - bl->upval = 1; - fs->needclose = 1; -} - - -/* -** Find a variable with the given name 'n'. If it is an upvalue, add -** this upvalue into all intermediate functions. If it is a global, set -** 'var' as 'void' as a flag. -*/ -static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { - if (fs == NULL) /* no more levels? */ - init_exp(var, VVOID, 0); /* default is global */ - else { - int v = searchvar(fs, n, var); /* look up locals at current level */ - if (v >= 0) { /* found? */ - if (v == VLOCAL && !base) - markupval(fs, var->u.var.vidx); /* local will be used as an upval */ - } - else { /* not found as local at current level; try upvalues */ - int idx = searchupvalue(fs, n); /* try existing upvalues */ - if (idx < 0) { /* not found? */ - singlevaraux(fs->prev, n, var, 0); /* try upper levels */ - if (var->k == VLOCAL || var->k == VUPVAL) /* local or upvalue? */ - idx = newupvalue(fs, n, var); /* will be a new upvalue */ - else /* it is a global or a constant */ - return; /* don't need to do anything at this level */ - } - init_exp(var, VUPVAL, idx); /* new or old upvalue */ - } - } -} - - -/* -** Find a variable with the given name 'n', handling global variables -** too. -*/ -static void singlevar (LexState *ls, expdesc *var) { - TString *varname = str_checkname(ls); - FuncState *fs = ls->fs; - singlevaraux(fs, varname, var, 1); - if (var->k == VVOID) { /* global name? */ - expdesc key; - singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ - lua_assert(var->k != VVOID); /* this one must exist */ - codestring(&key, varname); /* key is variable name */ - luaK_indexed(fs, var, &key); /* env[varname] */ - } -} - - -/* -** Adjust the number of results from an expression list 'e' with 'nexps' -** expressions to 'nvars' values. -*/ -static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { - FuncState *fs = ls->fs; - int needed = nvars - nexps; /* extra values needed */ - if (hasmultret(e->k)) { /* last expression has multiple returns? */ - int extra = needed + 1; /* discount last expression itself */ - if (extra < 0) - extra = 0; - luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ - } - else { - if (e->k != VVOID) /* at least one expression? */ - luaK_exp2nextreg(fs, e); /* close last expression */ - if (needed > 0) /* missing values? */ - luaK_nil(fs, fs->freereg, needed); /* complete with nils */ - } - if (needed > 0) - luaK_reserveregs(fs, needed); /* registers for extra values */ - else /* adding 'needed' is actually a subtraction */ - fs->freereg += needed; /* remove extra values */ -} - - -#define enterlevel(ls) luaE_incCstack(ls->L) - - -#define leavelevel(ls) ((ls)->L->nCcalls--) - - -/* -** Generates an error that a goto jumps into the scope of some -** local variable. -*/ -static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) { - const char *varname = getstr(getlocalvardesc(ls->fs, gt->nactvar)->vd.name); - const char *msg = " at line %d jumps into the scope of local '%s'"; - msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line, varname); - luaK_semerror(ls, msg); /* raise the error */ -} - - -/* -** Solves the goto at index 'g' to given 'label' and removes it -** from the list of pending goto's. -** If it jumps into the scope of some variable, raises an error. -*/ -static void solvegoto (LexState *ls, int g, Labeldesc *label) { - int i; - Labellist *gl = &ls->dyd->gt; /* list of goto's */ - Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */ - lua_assert(eqstr(gt->name, label->name)); - if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ - jumpscopeerror(ls, gt); - luaK_patchlist(ls->fs, gt->pc, label->pc); - for (i = g; i < gl->n - 1; i++) /* remove goto from pending list */ - gl->arr[i] = gl->arr[i + 1]; - gl->n--; -} - - -/* -** Search for an active label with the given name. -*/ -static Labeldesc *findlabel (LexState *ls, TString *name) { - int i; - Dyndata *dyd = ls->dyd; - /* check labels in current function for a match */ - for (i = ls->fs->firstlabel; i < dyd->label.n; i++) { - Labeldesc *lb = &dyd->label.arr[i]; - if (eqstr(lb->name, name)) /* correct label? */ - return lb; - } - return NULL; /* label not found */ -} - - -/* -** Adds a new label/goto in the corresponding list. -*/ -static int newlabelentry (LexState *ls, Labellist *l, TString *name, - int line, int pc) { - int n = l->n; - luaM_growvector(ls->L, l->arr, n, l->size, - Labeldesc, SHRT_MAX, "labels/gotos"); - l->arr[n].name = name; - l->arr[n].line = line; - l->arr[n].nactvar = ls->fs->nactvar; - l->arr[n].close = 0; - l->arr[n].pc = pc; - l->n = n + 1; - return n; -} - - -static int newgotoentry (LexState *ls, TString *name, int line, int pc) { - return newlabelentry(ls, &ls->dyd->gt, name, line, pc); -} - - -/* -** Solves forward jumps. Check whether new label 'lb' matches any -** pending gotos in current block and solves them. Return true -** if any of the goto's need to close upvalues. -*/ -static int solvegotos (LexState *ls, Labeldesc *lb) { - Labellist *gl = &ls->dyd->gt; - int i = ls->fs->bl->firstgoto; - int needsclose = 0; - while (i < gl->n) { - if (eqstr(gl->arr[i].name, lb->name)) { - needsclose |= gl->arr[i].close; - solvegoto(ls, i, lb); /* will remove 'i' from the list */ - } - else - i++; - } - return needsclose; -} - - -/* -** Create a new label with the given 'name' at the given 'line'. -** 'last' tells whether label is the last non-op statement in its -** block. Solves all pending goto's to this new label and adds -** a close instruction if necessary. -** Returns true iff it added a close instruction. -*/ -static int createlabel (LexState *ls, TString *name, int line, - int last) { - FuncState *fs = ls->fs; - Labellist *ll = &ls->dyd->label; - int l = newlabelentry(ls, ll, name, line, luaK_getlabel(fs)); - if (last) { /* label is last no-op statement in the block? */ - /* assume that locals are already out of scope */ - ll->arr[l].nactvar = fs->bl->nactvar; - } - if (solvegotos(ls, &ll->arr[l])) { /* need close? */ - luaK_codeABC(fs, OP_CLOSE, luaY_nvarstack(fs), 0, 0); - return 1; - } - return 0; -} - - -/* -** Adjust pending gotos to outer level of a block. -*/ -static void movegotosout (FuncState *fs, BlockCnt *bl) { - int i; - Labellist *gl = &fs->ls->dyd->gt; - /* correct pending gotos to current block */ - for (i = bl->firstgoto; i < gl->n; i++) { /* for each pending goto */ - Labeldesc *gt = &gl->arr[i]; - /* leaving a variable scope? */ - if (reglevel(fs, gt->nactvar) > reglevel(fs, bl->nactvar)) - gt->close |= bl->upval; /* jump may need a close */ - gt->nactvar = bl->nactvar; /* update goto level */ - } -} - - -static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { - bl->isloop = isloop; - bl->nactvar = fs->nactvar; - bl->firstlabel = fs->ls->dyd->label.n; - bl->firstgoto = fs->ls->dyd->gt.n; - bl->upval = 0; - bl->insidetbc = (fs->bl != NULL && fs->bl->insidetbc); - bl->previous = fs->bl; - fs->bl = bl; - lua_assert(fs->freereg == luaY_nvarstack(fs)); -} - - -/* -** generates an error for an undefined 'goto'. -*/ -static l_noret undefgoto (LexState *ls, Labeldesc *gt) { - const char *msg; - if (eqstr(gt->name, luaS_newliteral(ls->L, "break"))) { - msg = "break outside loop at line %d"; - msg = luaO_pushfstring(ls->L, msg, gt->line); - } - else { - msg = "no visible label '%s' for at line %d"; - msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); - } - luaK_semerror(ls, msg); -} - - -static void leaveblock (FuncState *fs) { - BlockCnt *bl = fs->bl; - LexState *ls = fs->ls; - int hasclose = 0; - int stklevel = reglevel(fs, bl->nactvar); /* level outside the block */ - if (bl->isloop) /* fix pending breaks? */ - hasclose = createlabel(ls, luaS_newliteral(ls->L, "break"), 0, 0); - if (!hasclose && bl->previous && bl->upval) - luaK_codeABC(fs, OP_CLOSE, stklevel, 0, 0); - fs->bl = bl->previous; - removevars(fs, bl->nactvar); - lua_assert(bl->nactvar == fs->nactvar); - fs->freereg = stklevel; /* free registers */ - ls->dyd->label.n = bl->firstlabel; /* remove local labels */ - if (bl->previous) /* inner block? */ - movegotosout(fs, bl); /* update pending gotos to outer block */ - else { - if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ - undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ - } -} - - -/* -** adds a new prototype into list of prototypes -*/ -static Proto *addprototype (LexState *ls) { - Proto *clp; - lua_State *L = ls->L; - FuncState *fs = ls->fs; - Proto *f = fs->f; /* prototype of current function */ - 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); - luaC_objbarrier(L, f, clp); - return clp; -} - - -/* -** codes instruction to create new closure in parent function. -** The OP_CLOSURE instruction uses the last available register, -** so that, if it invokes the GC, the GC knows which registers -** are in use at that time. - -*/ -static void codeclosure (LexState *ls, expdesc *v) { - FuncState *fs = ls->fs->prev; - init_exp(v, VRELOC, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); - luaK_exp2nextreg(fs, v); /* fix it at the last register */ -} - - -static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { - Proto *f = fs->f; - fs->prev = ls->fs; /* linked list of funcstates */ - fs->ls = ls; - ls->fs = fs; - fs->pc = 0; - fs->previousline = f->linedefined; - fs->iwthabs = 0; - fs->lasttarget = 0; - fs->freereg = 0; - fs->nk = 0; - fs->nabslineinfo = 0; - fs->np = 0; - fs->nups = 0; - fs->ndebugvars = 0; - fs->nactvar = 0; - fs->needclose = 0; - fs->firstlocal = ls->dyd->actvar.n; - fs->firstlabel = ls->dyd->label.n; - fs->bl = NULL; - f->source = ls->source; - luaC_objbarrier(ls->L, f, f->source); - f->maxstacksize = 2; /* registers 0/1 are always valid */ - enterblock(fs, bl, 0); -} - - -static void close_func (LexState *ls) { - lua_State *L = ls->L; - FuncState *fs = ls->fs; - Proto *f = fs->f; - luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ - leaveblock(fs); - lua_assert(fs->bl == NULL); - luaK_finish(fs); - luaM_shrinkvector(L, f->code, f->sizecode, fs->pc, Instruction); - luaM_shrinkvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte); - luaM_shrinkvector(L, f->abslineinfo, f->sizeabslineinfo, - fs->nabslineinfo, AbsLineInfo); - luaM_shrinkvector(L, f->k, f->sizek, fs->nk, TValue); - luaM_shrinkvector(L, f->p, f->sizep, fs->np, Proto *); - luaM_shrinkvector(L, f->locvars, f->sizelocvars, fs->ndebugvars, LocVar); - luaM_shrinkvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); - ls->fs = fs->prev; - luaC_checkGC(L); -} - - - -/*============================================================*/ -/* GRAMMAR RULES */ -/*============================================================*/ - - -/* -** check whether current token is in the follow set of a block. -** 'until' closes syntactical blocks, but do not close scope, -** so it is handled in separate. -*/ -static int block_follow (LexState *ls, int withuntil) { - switch (ls->t.token) { - case TK_ELSE: case TK_ELSEIF: - case TK_END: case TK_EOS: - return 1; - case TK_UNTIL: return withuntil; - default: return 0; - } -} - - -static void statlist (LexState *ls) { - /* statlist -> { stat [';'] } */ - while (!block_follow(ls, 1)) { - if (ls->t.token == TK_RETURN) { - statement(ls); - return; /* 'return' must be last statement */ - } - statement(ls); - } -} - - -static void fieldsel (LexState *ls, expdesc *v) { - /* fieldsel -> ['.' | ':'] NAME */ - FuncState *fs = ls->fs; - expdesc key; - luaK_exp2anyregup(fs, v); - luaX_next(ls); /* skip the dot or colon */ - codename(ls, &key); - luaK_indexed(fs, v, &key); -} - - -static void yindex (LexState *ls, expdesc *v) { - /* index -> '[' expr ']' */ - luaX_next(ls); /* skip the '[' */ - expr(ls, v); - luaK_exp2val(ls->fs, v); - checknext(ls, ']'); -} - - -/* -** {====================================================================== -** Rules for Constructors -** ======================================================================= -*/ - - -typedef struct ConsControl { - expdesc v; /* last list item read */ - expdesc *t; /* table descriptor */ - int nh; /* total number of 'record' elements */ - int na; /* number of array elements already stored */ - int tostore; /* number of array elements pending to be stored */ -} ConsControl; - - -static void recfield (LexState *ls, ConsControl *cc) { - /* recfield -> (NAME | '['exp']') = exp */ - FuncState *fs = ls->fs; - int reg = ls->fs->freereg; - expdesc tab, key, val; - if (ls->t.token == TK_NAME) { - checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); - codename(ls, &key); - } - else /* ls->t.token == '[' */ - yindex(ls, &key); - cc->nh++; - checknext(ls, '='); - tab = *cc->t; - luaK_indexed(fs, &tab, &key); - expr(ls, &val); - luaK_storevar(fs, &tab, &val); - fs->freereg = reg; /* free registers */ -} - - -static void closelistfield (FuncState *fs, ConsControl *cc) { - if (cc->v.k == VVOID) return; /* there is no list item */ - luaK_exp2nextreg(fs, &cc->v); - cc->v.k = VVOID; - if (cc->tostore == LFIELDS_PER_FLUSH) { - luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ - cc->na += cc->tostore; - cc->tostore = 0; /* no more items pending */ - } -} - - -static void lastlistfield (FuncState *fs, ConsControl *cc) { - if (cc->tostore == 0) return; - if (hasmultret(cc->v.k)) { - luaK_setmultret(fs, &cc->v); - luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); - cc->na--; /* do not count last expression (unknown number of elements) */ - } - else { - if (cc->v.k != VVOID) - luaK_exp2nextreg(fs, &cc->v); - luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); - } - cc->na += cc->tostore; -} - - -static void listfield (LexState *ls, ConsControl *cc) { - /* listfield -> exp */ - expr(ls, &cc->v); - cc->tostore++; -} - - -static void field (LexState *ls, ConsControl *cc) { - /* field -> listfield | recfield */ - switch(ls->t.token) { - case TK_NAME: { /* may be 'listfield' or 'recfield' */ - if (luaX_lookahead(ls) != '=') /* expression? */ - listfield(ls, cc); - else - recfield(ls, cc); - break; - } - case '[': { - recfield(ls, cc); - break; - } - default: { - listfield(ls, cc); - break; - } - } -} - - -static void constructor (LexState *ls, expdesc *t) { - /* constructor -> '{' [ field { sep field } [sep] ] '}' - sep -> ',' | ';' */ - FuncState *fs = ls->fs; - int line = ls->linenumber; - int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); - ConsControl cc; - luaK_code(fs, 0); /* space for extra arg. */ - cc.na = cc.nh = cc.tostore = 0; - cc.t = t; - init_exp(t, VNONRELOC, fs->freereg); /* table will be at stack top */ - luaK_reserveregs(fs, 1); - init_exp(&cc.v, VVOID, 0); /* no value (yet) */ - checknext(ls, '{'); - do { - lua_assert(cc.v.k == VVOID || cc.tostore > 0); - if (ls->t.token == '}') break; - closelistfield(fs, &cc); - field(ls, &cc); - } while (testnext(ls, ',') || testnext(ls, ';')); - check_match(ls, '}', '{', line); - lastlistfield(fs, &cc); - luaK_settablesize(fs, pc, t->u.info, cc.na, cc.nh); -} - -/* }====================================================================== */ - - -static void setvararg (FuncState *fs, int nparams) { - fs->f->is_vararg = 1; - luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0); -} - - -static void parlist (LexState *ls) { - /* parlist -> [ {NAME ','} (NAME | '...') ] */ - FuncState *fs = ls->fs; - Proto *f = fs->f; - int nparams = 0; - int isvararg = 0; - if (ls->t.token != ')') { /* is 'parlist' not empty? */ - do { - switch (ls->t.token) { - case TK_NAME: { - new_localvar(ls, str_checkname(ls)); - nparams++; - break; - } - case TK_DOTS: { - luaX_next(ls); - isvararg = 1; - break; - } - default: luaX_syntaxerror(ls, " or '...' expected"); - } - } while (!isvararg && testnext(ls, ',')); - } - adjustlocalvars(ls, nparams); - f->numparams = cast_byte(fs->nactvar); - if (isvararg) - setvararg(fs, f->numparams); /* declared vararg */ - luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */ -} - - -static void body (LexState *ls, expdesc *e, int ismethod, int line) { - /* body -> '(' parlist ')' block END */ - FuncState new_fs; - BlockCnt bl; - new_fs.f = addprototype(ls); - new_fs.f->linedefined = line; - open_func(ls, &new_fs, &bl); - checknext(ls, '('); - if (ismethod) { - new_localvarliteral(ls, "self"); /* create 'self' parameter */ - adjustlocalvars(ls, 1); - } - parlist(ls); - checknext(ls, ')'); - statlist(ls); - new_fs.f->lastlinedefined = ls->linenumber; - check_match(ls, TK_END, TK_FUNCTION, line); - codeclosure(ls, e); - close_func(ls); -} - - -static int explist (LexState *ls, expdesc *v) { - /* explist -> expr { ',' expr } */ - int n = 1; /* at least one expression */ - expr(ls, v); - while (testnext(ls, ',')) { - luaK_exp2nextreg(ls->fs, v); - expr(ls, v); - n++; - } - return n; -} - - -static void funcargs (LexState *ls, expdesc *f, int line) { - FuncState *fs = ls->fs; - expdesc args; - int base, nparams; - switch (ls->t.token) { - case '(': { /* funcargs -> '(' [ explist ] ')' */ - luaX_next(ls); - if (ls->t.token == ')') /* arg list is empty? */ - args.k = VVOID; - else { - explist(ls, &args); - if (hasmultret(args.k)) - luaK_setmultret(fs, &args); - } - check_match(ls, ')', '(', line); - break; - } - case '{': { /* funcargs -> constructor */ - constructor(ls, &args); - break; - } - case TK_STRING: { /* funcargs -> STRING */ - codestring(&args, ls->t.seminfo.ts); - luaX_next(ls); /* must use 'seminfo' before 'next' */ - break; - } - default: { - luaX_syntaxerror(ls, "function arguments expected"); - } - } - lua_assert(f->k == VNONRELOC); - base = f->u.info; /* base register for call */ - if (hasmultret(args.k)) - nparams = LUA_MULTRET; /* open call */ - else { - if (args.k != VVOID) - luaK_exp2nextreg(fs, &args); /* close last argument */ - nparams = fs->freereg - (base+1); - } - init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); - luaK_fixline(fs, line); - fs->freereg = base+1; /* call remove function and arguments and leaves - (unless changed) one result */ -} - - - - -/* -** {====================================================================== -** Expression parsing -** ======================================================================= -*/ - - -static void primaryexp (LexState *ls, expdesc *v) { - /* primaryexp -> NAME | '(' expr ')' */ - switch (ls->t.token) { - case '(': { - int line = ls->linenumber; - luaX_next(ls); - expr(ls, v); - check_match(ls, ')', '(', line); - luaK_dischargevars(ls->fs, v); - return; - } - case TK_NAME: { - singlevar(ls, v); - return; - } - default: { - luaX_syntaxerror(ls, "unexpected symbol"); - } - } -} - - -static void suffixedexp (LexState *ls, expdesc *v) { - /* suffixedexp -> - primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ - FuncState *fs = ls->fs; - int line = ls->linenumber; - primaryexp(ls, v); - for (;;) { - switch (ls->t.token) { - case '.': { /* fieldsel */ - fieldsel(ls, v); - break; - } - case '[': { /* '[' exp ']' */ - expdesc key; - luaK_exp2anyregup(fs, v); - yindex(ls, &key); - luaK_indexed(fs, v, &key); - break; - } - case ':': { /* ':' NAME funcargs */ - expdesc key; - luaX_next(ls); - codename(ls, &key); - luaK_self(fs, v, &key); - funcargs(ls, v, line); - break; - } - case '(': case TK_STRING: case '{': { /* funcargs */ - luaK_exp2nextreg(fs, v); - funcargs(ls, v, line); - break; - } - default: return; - } - } -} - - -static void simpleexp (LexState *ls, expdesc *v) { - /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... | - constructor | FUNCTION body | suffixedexp */ - switch (ls->t.token) { - case TK_FLT: { - init_exp(v, VKFLT, 0); - v->u.nval = ls->t.seminfo.r; - break; - } - case TK_INT: { - init_exp(v, VKINT, 0); - v->u.ival = ls->t.seminfo.i; - break; - } - case TK_STRING: { - codestring(v, ls->t.seminfo.ts); - break; - } - case TK_NIL: { - init_exp(v, VNIL, 0); - break; - } - case TK_TRUE: { - init_exp(v, VTRUE, 0); - break; - } - case TK_FALSE: { - init_exp(v, VFALSE, 0); - break; - } - case TK_DOTS: { /* vararg */ - FuncState *fs = ls->fs; - check_condition(ls, fs->f->is_vararg, - "cannot use '...' outside a vararg function"); - init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 0, 1)); - break; - } - case '{': { /* constructor */ - constructor(ls, v); - return; - } - case TK_FUNCTION: { - luaX_next(ls); - body(ls, v, 0, ls->linenumber); - return; - } - default: { - suffixedexp(ls, v); - return; - } - } - luaX_next(ls); -} - - -static UnOpr getunopr (int op) { - switch (op) { - case TK_NOT: return OPR_NOT; - case '-': return OPR_MINUS; - case '~': return OPR_BNOT; - case '#': return OPR_LEN; - default: return OPR_NOUNOPR; - } -} - - -static BinOpr getbinopr (int op) { - switch (op) { - case '+': return OPR_ADD; - case '-': return OPR_SUB; - case '*': return OPR_MUL; - case '%': return OPR_MOD; - case '^': return OPR_POW; - case '/': return OPR_DIV; - case TK_IDIV: return OPR_IDIV; - case '&': return OPR_BAND; - case '|': return OPR_BOR; - case '~': return OPR_BXOR; - case TK_SHL: return OPR_SHL; - case TK_SHR: return OPR_SHR; - case TK_CONCAT: return OPR_CONCAT; - case TK_NE: return OPR_NE; - case TK_EQ: return OPR_EQ; - case '<': return OPR_LT; - case TK_LE: return OPR_LE; - case '>': return OPR_GT; - case TK_GE: return OPR_GE; - case TK_AND: return OPR_AND; - case TK_OR: return OPR_OR; - default: return OPR_NOBINOPR; - } -} - - -/* -** Priority table for binary operators. -*/ -static const struct { - lu_byte left; /* left priority for each binary operator */ - lu_byte right; /* right priority */ -} priority[] = { /* ORDER OPR */ - {10, 10}, {10, 10}, /* '+' '-' */ - {11, 11}, {11, 11}, /* '*' '%' */ - {14, 13}, /* '^' (right associative) */ - {11, 11}, {11, 11}, /* '/' '//' */ - {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ - {7, 7}, {7, 7}, /* '<<' '>>' */ - {9, 8}, /* '..' (right associative) */ - {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ - {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ - {2, 2}, {1, 1} /* and, or */ -}; - -#define UNARY_PRIORITY 12 /* priority for unary operators */ - - -/* -** subexpr -> (simpleexp | unop subexpr) { binop subexpr } -** where 'binop' is any binary operator with a priority higher than 'limit' -*/ -static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { - BinOpr op; - UnOpr uop; - enterlevel(ls); - uop = getunopr(ls->t.token); - if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */ - int line = ls->linenumber; - luaX_next(ls); /* skip operator */ - subexpr(ls, v, UNARY_PRIORITY); - luaK_prefix(ls->fs, uop, v, line); - } - else simpleexp(ls, v); - /* expand while operators have priorities higher than 'limit' */ - op = getbinopr(ls->t.token); - while (op != OPR_NOBINOPR && priority[op].left > limit) { - expdesc v2; - BinOpr nextop; - int line = ls->linenumber; - luaX_next(ls); /* skip operator */ - luaK_infix(ls->fs, op, v); - /* read sub-expression with higher priority */ - nextop = subexpr(ls, &v2, priority[op].right); - luaK_posfix(ls->fs, op, v, &v2, line); - op = nextop; - } - leavelevel(ls); - return op; /* return first untreated operator */ -} - - -static void expr (LexState *ls, expdesc *v) { - subexpr(ls, v, 0); -} - -/* }==================================================================== */ - - - -/* -** {====================================================================== -** Rules for Statements -** ======================================================================= -*/ - - -static void block (LexState *ls) { - /* block -> statlist */ - FuncState *fs = ls->fs; - BlockCnt bl; - enterblock(fs, &bl, 0); - statlist(ls); - leaveblock(fs); -} - - -/* -** structure to chain all variables in the left-hand side of an -** assignment -*/ -struct LHS_assign { - struct LHS_assign *prev; - expdesc v; /* variable (global, local, upvalue, or indexed) */ -}; - - -/* -** check whether, in an assignment to an upvalue/local variable, the -** upvalue/local variable is begin used in a previous assignment to a -** table. If so, save original upvalue/local value in a safe place and -** use this safe copy in the previous assignment. -*/ -static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { - FuncState *fs = ls->fs; - int extra = fs->freereg; /* eventual position to save local variable */ - int conflict = 0; - for (; lh; lh = lh->prev) { /* check all previous assignments */ - if (vkisindexed(lh->v.k)) { /* assignment to table field? */ - if (lh->v.k == VINDEXUP) { /* is table an upvalue? */ - if (v->k == VUPVAL && lh->v.u.ind.t == v->u.info) { - conflict = 1; /* table is the upvalue being assigned now */ - lh->v.k = VINDEXSTR; - lh->v.u.ind.t = extra; /* assignment will use safe copy */ - } - } - else { /* table is a register */ - if (v->k == VLOCAL && lh->v.u.ind.t == v->u.var.ridx) { - conflict = 1; /* table is the local being assigned now */ - lh->v.u.ind.t = extra; /* assignment will use safe copy */ - } - /* is index the local being assigned? */ - if (lh->v.k == VINDEXED && v->k == VLOCAL && - lh->v.u.ind.idx == v->u.var.ridx) { - conflict = 1; - lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ - } - } - } - } - if (conflict) { - /* copy upvalue/local value to a temporary (in position 'extra') */ - if (v->k == VLOCAL) - luaK_codeABC(fs, OP_MOVE, extra, v->u.var.ridx, 0); - else - luaK_codeABC(fs, OP_GETUPVAL, extra, v->u.info, 0); - luaK_reserveregs(fs, 1); - } -} - -/* -** Parse and compile a multiple assignment. The first "variable" -** (a 'suffixedexp') was already read by the caller. -** -** assignment -> suffixedexp restassign -** restassign -> ',' suffixedexp restassign | '=' explist -*/ -static void restassign (LexState *ls, struct LHS_assign *lh, int nvars) { - expdesc e; - check_condition(ls, vkisvar(lh->v.k), "syntax error"); - check_readonly(ls, &lh->v); - if (testnext(ls, ',')) { /* restassign -> ',' suffixedexp restassign */ - struct LHS_assign nv; - nv.prev = lh; - suffixedexp(ls, &nv.v); - if (!vkisindexed(nv.v.k)) - check_conflict(ls, lh, &nv.v); - enterlevel(ls); /* control recursion depth */ - restassign(ls, &nv, nvars+1); - leavelevel(ls); - } - else { /* restassign -> '=' explist */ - int nexps; - checknext(ls, '='); - nexps = explist(ls, &e); - if (nexps != nvars) - adjust_assign(ls, nvars, nexps, &e); - else { - luaK_setoneret(ls->fs, &e); /* close last expression */ - luaK_storevar(ls->fs, &lh->v, &e); - return; /* avoid default */ - } - } - init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ - luaK_storevar(ls->fs, &lh->v, &e); -} - - -static int cond (LexState *ls) { - /* cond -> exp */ - expdesc v; - expr(ls, &v); /* read condition */ - if (v.k == VNIL) v.k = VFALSE; /* 'falses' are all equal here */ - luaK_goiftrue(ls->fs, &v); - return v.f; -} - - -static void gotostat (LexState *ls) { - FuncState *fs = ls->fs; - int line = ls->linenumber; - TString *name = str_checkname(ls); /* label's name */ - Labeldesc *lb = findlabel(ls, name); - if (lb == NULL) /* no label? */ - /* forward jump; will be resolved when the label is declared */ - newgotoentry(ls, name, line, luaK_jump(fs)); - else { /* found a label */ - /* backward jump; will be resolved here */ - int lblevel = reglevel(fs, lb->nactvar); /* label level */ - if (luaY_nvarstack(fs) > lblevel) /* leaving the scope of a variable? */ - luaK_codeABC(fs, OP_CLOSE, lblevel, 0, 0); - /* create jump and link it to the label */ - luaK_patchlist(fs, luaK_jump(fs), lb->pc); - } -} - - -/* -** Break statement. Semantically equivalent to "goto break". -*/ -static void breakstat (LexState *ls) { - int line = ls->linenumber; - luaX_next(ls); /* skip break */ - newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, luaK_jump(ls->fs)); -} - - -/* -** Check whether there is already a label with the given 'name'. -*/ -static void checkrepeated (LexState *ls, TString *name) { - Labeldesc *lb = findlabel(ls, name); - if (l_unlikely(lb != NULL)) { /* already defined? */ - const char *msg = "label '%s' already defined on line %d"; - msg = luaO_pushfstring(ls->L, msg, getstr(name), lb->line); - luaK_semerror(ls, msg); /* error */ - } -} - - -static void labelstat (LexState *ls, TString *name, int line) { - /* label -> '::' NAME '::' */ - checknext(ls, TK_DBCOLON); /* skip double colon */ - while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) - statement(ls); /* skip other no-op statements */ - checkrepeated(ls, name); /* check for repeated labels */ - createlabel(ls, name, line, block_follow(ls, 0)); -} - - -static void whilestat (LexState *ls, int line) { - /* whilestat -> WHILE cond DO block END */ - FuncState *fs = ls->fs; - int whileinit; - int condexit; - BlockCnt bl; - luaX_next(ls); /* skip WHILE */ - whileinit = luaK_getlabel(fs); - condexit = cond(ls); - enterblock(fs, &bl, 1); - checknext(ls, TK_DO); - block(ls); - luaK_jumpto(fs, whileinit); - check_match(ls, TK_END, TK_WHILE, line); - leaveblock(fs); - luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ -} - - -static void repeatstat (LexState *ls, int line) { - /* repeatstat -> REPEAT block UNTIL cond */ - int condexit; - FuncState *fs = ls->fs; - int repeat_init = luaK_getlabel(fs); - BlockCnt bl1, bl2; - enterblock(fs, &bl1, 1); /* loop block */ - enterblock(fs, &bl2, 0); /* scope block */ - luaX_next(ls); /* skip REPEAT */ - statlist(ls); - check_match(ls, TK_UNTIL, TK_REPEAT, line); - condexit = cond(ls); /* read condition (inside scope block) */ - leaveblock(fs); /* finish scope */ - if (bl2.upval) { /* upvalues? */ - int exit = luaK_jump(fs); /* normal exit must jump over fix */ - luaK_patchtohere(fs, condexit); /* repetition must close upvalues */ - luaK_codeABC(fs, OP_CLOSE, reglevel(fs, bl2.nactvar), 0, 0); - condexit = luaK_jump(fs); /* repeat after closing upvalues */ - luaK_patchtohere(fs, exit); /* normal exit comes to here */ - } - luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ - leaveblock(fs); /* finish loop */ -} - - -/* -** Read an expression and generate code to put its results in next -** stack slot. -** -*/ -static void exp1 (LexState *ls) { - expdesc e; - expr(ls, &e); - luaK_exp2nextreg(ls->fs, &e); - lua_assert(e.k == VNONRELOC); -} - - -/* -** Fix for instruction at position 'pc' to jump to 'dest'. -** (Jump addresses are relative in Lua). 'back' true means -** a back jump. -*/ -static void fixforjump (FuncState *fs, int pc, int dest, int back) { - Instruction *jmp = &fs->f->code[pc]; - int offset = dest - (pc + 1); - if (back) - offset = -offset; - if (l_unlikely(offset > MAXARG_Bx)) - luaX_syntaxerror(fs->ls, "control structure too long"); - SETARG_Bx(*jmp, offset); -} - - -/* -** Generate code for a 'for' loop. -*/ -static void forbody (LexState *ls, int base, int line, int nvars, int isgen) { - /* forbody -> DO block */ - static const OpCode forprep[2] = {OP_FORPREP, OP_TFORPREP}; - static const OpCode forloop[2] = {OP_FORLOOP, OP_TFORLOOP}; - BlockCnt bl; - FuncState *fs = ls->fs; - int prep, endfor; - checknext(ls, TK_DO); - prep = luaK_codeABx(fs, forprep[isgen], base, 0); - enterblock(fs, &bl, 0); /* scope for declared variables */ - adjustlocalvars(ls, nvars); - luaK_reserveregs(fs, nvars); - block(ls); - leaveblock(fs); /* end of scope for declared variables */ - fixforjump(fs, prep, luaK_getlabel(fs), 0); - if (isgen) { /* generic for? */ - luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); - luaK_fixline(fs, line); - } - endfor = luaK_codeABx(fs, forloop[isgen], base, 0); - fixforjump(fs, endfor, prep + 1, 1); - luaK_fixline(fs, line); -} - - -static void fornum (LexState *ls, TString *varname, int line) { - /* fornum -> NAME = exp,exp[,exp] forbody */ - FuncState *fs = ls->fs; - int base = fs->freereg; - new_localvarliteral(ls, "(for state)"); - new_localvarliteral(ls, "(for state)"); - new_localvarliteral(ls, "(for state)"); - new_localvar(ls, varname); - checknext(ls, '='); - exp1(ls); /* initial value */ - checknext(ls, ','); - exp1(ls); /* limit */ - if (testnext(ls, ',')) - exp1(ls); /* optional step */ - else { /* default step = 1 */ - luaK_int(fs, fs->freereg, 1); - luaK_reserveregs(fs, 1); - } - adjustlocalvars(ls, 3); /* control variables */ - forbody(ls, base, line, 1, 0); -} - - -static void forlist (LexState *ls, TString *indexname) { - /* forlist -> NAME {,NAME} IN explist forbody */ - FuncState *fs = ls->fs; - expdesc e; - int nvars = 5; /* gen, state, control, toclose, 'indexname' */ - int line; - int base = fs->freereg; - /* create control variables */ - new_localvarliteral(ls, "(for state)"); - new_localvarliteral(ls, "(for state)"); - new_localvarliteral(ls, "(for state)"); - new_localvarliteral(ls, "(for state)"); - /* create declared variables */ - new_localvar(ls, indexname); - while (testnext(ls, ',')) { - new_localvar(ls, str_checkname(ls)); - nvars++; - } - checknext(ls, TK_IN); - line = ls->linenumber; - adjust_assign(ls, 4, explist(ls, &e), &e); - adjustlocalvars(ls, 4); /* control variables */ - markupval(fs, fs->nactvar); /* last control var. must be closed */ - luaK_checkstack(fs, 3); /* extra space to call generator */ - forbody(ls, base, line, nvars - 4, 1); -} - - -static void forstat (LexState *ls, int line) { - /* forstat -> FOR (fornum | forlist) END */ - FuncState *fs = ls->fs; - TString *varname; - BlockCnt bl; - enterblock(fs, &bl, 1); /* scope for loop and control variables */ - luaX_next(ls); /* skip 'for' */ - varname = str_checkname(ls); /* first variable name */ - switch (ls->t.token) { - case '=': fornum(ls, varname, line); break; - case ',': case TK_IN: forlist(ls, varname); break; - default: luaX_syntaxerror(ls, "'=' or 'in' expected"); - } - check_match(ls, TK_END, TK_FOR, line); - leaveblock(fs); /* loop scope ('break' jumps to this point) */ -} - - -static void test_then_block (LexState *ls, int *escapelist) { - /* test_then_block -> [IF | ELSEIF] cond THEN block */ - BlockCnt bl; - FuncState *fs = ls->fs; - expdesc v; - int jf; /* instruction to skip 'then' code (if condition is false) */ - luaX_next(ls); /* skip IF or ELSEIF */ - expr(ls, &v); /* read condition */ - checknext(ls, TK_THEN); - if (ls->t.token == TK_BREAK) { /* 'if x then break' ? */ - int line = ls->linenumber; - luaK_goiffalse(ls->fs, &v); /* will jump if condition is true */ - luaX_next(ls); /* skip 'break' */ - enterblock(fs, &bl, 0); /* must enter block before 'goto' */ - newgotoentry(ls, luaS_newliteral(ls->L, "break"), line, v.t); - while (testnext(ls, ';')) {} /* skip semicolons */ - if (block_follow(ls, 0)) { /* jump is the entire block? */ - leaveblock(fs); - return; /* and that is it */ - } - else /* must skip over 'then' part if condition is false */ - jf = luaK_jump(fs); - } - else { /* regular case (not a break) */ - luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ - enterblock(fs, &bl, 0); - jf = v.f; - } - statlist(ls); /* 'then' part */ - leaveblock(fs); - if (ls->t.token == TK_ELSE || - ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ - luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ - luaK_patchtohere(fs, jf); -} - - -static void ifstat (LexState *ls, int line) { - /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ - FuncState *fs = ls->fs; - int escapelist = NO_JUMP; /* exit list for finished parts */ - test_then_block(ls, &escapelist); /* IF cond THEN block */ - while (ls->t.token == TK_ELSEIF) - test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ - if (testnext(ls, TK_ELSE)) - block(ls); /* 'else' part */ - check_match(ls, TK_END, TK_IF, line); - luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ -} - - -static void localfunc (LexState *ls) { - expdesc b; - FuncState *fs = ls->fs; - int fvar = fs->nactvar; /* function's variable index */ - new_localvar(ls, str_checkname(ls)); /* new local variable */ - adjustlocalvars(ls, 1); /* enter its scope */ - body(ls, &b, 0, ls->linenumber); /* function created in next register */ - /* debug information will only see the variable after this point! */ - localdebuginfo(fs, fvar)->startpc = fs->pc; -} - - -static int getlocalattribute (LexState *ls) { - /* ATTRIB -> ['<' Name '>'] */ - if (testnext(ls, '<')) { - const char *attr = getstr(str_checkname(ls)); - checknext(ls, '>'); - if (strcmp(attr, "const") == 0) - return RDKCONST; /* read-only variable */ - else if (strcmp(attr, "close") == 0) - return RDKTOCLOSE; /* to-be-closed variable */ - else - luaK_semerror(ls, - luaO_pushfstring(ls->L, "unknown attribute '%s'", attr)); - } - return VDKREG; /* regular variable */ -} - - -static void checktoclose (LexState *ls, int level) { - if (level != -1) { /* is there a to-be-closed variable? */ - FuncState *fs = ls->fs; - markupval(fs, level + 1); - fs->bl->insidetbc = 1; /* in the scope of a to-be-closed variable */ - luaK_codeABC(fs, OP_TBC, reglevel(fs, level), 0, 0); - } -} - - -static void localstat (LexState *ls) { - /* stat -> LOCAL NAME ATTRIB { ',' NAME ATTRIB } ['=' explist] */ - FuncState *fs = ls->fs; - int toclose = -1; /* index of to-be-closed variable (if any) */ - Vardesc *var; /* last variable */ - int vidx, kind; /* index and kind of last variable */ - int nvars = 0; - int nexps; - expdesc e; - do { - vidx = new_localvar(ls, str_checkname(ls)); - kind = getlocalattribute(ls); - getlocalvardesc(fs, vidx)->vd.kind = kind; - if (kind == RDKTOCLOSE) { /* to-be-closed? */ - if (toclose != -1) /* one already present? */ - luaK_semerror(ls, "multiple to-be-closed variables in local list"); - toclose = fs->nactvar + nvars; - } - nvars++; - } while (testnext(ls, ',')); - if (testnext(ls, '=')) - nexps = explist(ls, &e); - else { - e.k = VVOID; - nexps = 0; - } - var = getlocalvardesc(fs, vidx); /* get last variable */ - if (nvars == nexps && /* no adjustments? */ - var->vd.kind == RDKCONST && /* last variable is const? */ - luaK_exp2const(fs, &e, &var->k)) { /* compile-time constant? */ - var->vd.kind = RDKCTC; /* variable is a compile-time constant */ - adjustlocalvars(ls, nvars - 1); /* exclude last variable */ - fs->nactvar++; /* but count it */ - } - else { - adjust_assign(ls, nvars, nexps, &e); - adjustlocalvars(ls, nvars); - } - checktoclose(ls, toclose); -} - - -static int funcname (LexState *ls, expdesc *v) { - /* funcname -> NAME {fieldsel} [':' NAME] */ - int ismethod = 0; - singlevar(ls, v); - while (ls->t.token == '.') - fieldsel(ls, v); - if (ls->t.token == ':') { - ismethod = 1; - fieldsel(ls, v); - } - return ismethod; -} - - -static void funcstat (LexState *ls, int line) { - /* funcstat -> FUNCTION funcname body */ - int ismethod; - expdesc v, b; - luaX_next(ls); /* skip FUNCTION */ - ismethod = funcname(ls, &v); - body(ls, &b, ismethod, line); - luaK_storevar(ls->fs, &v, &b); - luaK_fixline(ls->fs, line); /* definition "happens" in the first line */ -} - - -static void exprstat (LexState *ls) { - /* stat -> func | assignment */ - FuncState *fs = ls->fs; - struct LHS_assign v; - suffixedexp(ls, &v.v); - if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ - v.prev = NULL; - restassign(ls, &v, 1); - } - else { /* stat -> func */ - Instruction *inst; - check_condition(ls, v.v.k == VCALL, "syntax error"); - inst = &getinstruction(fs, &v.v); - SETARG_C(*inst, 1); /* call statement uses no results */ - } -} - - -static void retstat (LexState *ls) { - /* stat -> RETURN [explist] [';'] */ - FuncState *fs = ls->fs; - expdesc e; - int nret; /* number of values being returned */ - int first = luaY_nvarstack(fs); /* first slot to be returned */ - if (block_follow(ls, 1) || ls->t.token == ';') - nret = 0; /* return no values */ - else { - nret = explist(ls, &e); /* optional return values */ - if (hasmultret(e.k)) { - luaK_setmultret(fs, &e); - if (e.k == VCALL && nret == 1 && !fs->bl->insidetbc) { /* tail call? */ - SET_OPCODE(getinstruction(fs,&e), OP_TAILCALL); - lua_assert(GETARG_A(getinstruction(fs,&e)) == luaY_nvarstack(fs)); - } - nret = LUA_MULTRET; /* return all values */ - } - else { - if (nret == 1) /* only one single value? */ - first = luaK_exp2anyreg(fs, &e); /* can use original slot */ - else { /* values must go to the top of the stack */ - luaK_exp2nextreg(fs, &e); - lua_assert(nret == fs->freereg - first); - } - } - } - luaK_ret(fs, first, nret); - testnext(ls, ';'); /* skip optional semicolon */ -} - - -static void statement (LexState *ls) { - int line = ls->linenumber; /* may be needed for error messages */ - enterlevel(ls); - switch (ls->t.token) { - case ';': { /* stat -> ';' (empty statement) */ - luaX_next(ls); /* skip ';' */ - break; - } - case TK_IF: { /* stat -> ifstat */ - ifstat(ls, line); - break; - } - case TK_WHILE: { /* stat -> whilestat */ - whilestat(ls, line); - break; - } - case TK_DO: { /* stat -> DO block END */ - luaX_next(ls); /* skip DO */ - block(ls); - check_match(ls, TK_END, TK_DO, line); - break; - } - case TK_FOR: { /* stat -> forstat */ - forstat(ls, line); - break; - } - case TK_REPEAT: { /* stat -> repeatstat */ - repeatstat(ls, line); - break; - } - case TK_FUNCTION: { /* stat -> funcstat */ - funcstat(ls, line); - break; - } - case TK_LOCAL: { /* stat -> localstat */ - luaX_next(ls); /* skip LOCAL */ - if (testnext(ls, TK_FUNCTION)) /* local function? */ - localfunc(ls); - else - localstat(ls); - break; - } - case TK_DBCOLON: { /* stat -> label */ - luaX_next(ls); /* skip double colon */ - labelstat(ls, str_checkname(ls), line); - break; - } - case TK_RETURN: { /* stat -> retstat */ - luaX_next(ls); /* skip RETURN */ - retstat(ls); - break; - } - case TK_BREAK: { /* stat -> breakstat */ - breakstat(ls); - break; - } - case TK_GOTO: { /* stat -> 'goto' NAME */ - luaX_next(ls); /* skip 'goto' */ - gotostat(ls); - break; - } - default: { /* stat -> func | assignment */ - exprstat(ls); - break; - } - } - lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && - ls->fs->freereg >= luaY_nvarstack(ls->fs)); - ls->fs->freereg = luaY_nvarstack(ls->fs); /* free registers */ - leavelevel(ls); -} - -/* }====================================================================== */ - - -/* -** compiles the main function, which is a regular vararg function with an -** upvalue named LUA_ENV -*/ -static void mainfunc (LexState *ls, FuncState *fs) { - BlockCnt bl; - Upvaldesc *env; - open_func(ls, fs, &bl); - setvararg(fs, 0); /* main function is always declared vararg */ - env = allocupvalue(fs); /* ...set environment upvalue */ - env->instack = 1; - env->idx = 0; - env->kind = VDKREG; - env->name = ls->envn; - luaC_objbarrier(ls->L, fs->f, env->name); - luaX_next(ls); /* read first token */ - statlist(ls); /* parse main body */ - check(ls, TK_EOS); - close_func(ls); -} - - -LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, - Dyndata *dyd, const char *name, int firstchar) { - LexState lexstate; - FuncState funcstate; - LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ - setclLvalue2s(L, L->top, cl); /* anchor it (to avoid being collected) */ - luaD_inctop(L); - lexstate.h = luaH_new(L); /* create table for scanner */ - sethvalue2s(L, L->top, lexstate.h); /* anchor it */ - luaD_inctop(L); - funcstate.f = cl->p = luaF_newproto(L); - luaC_objbarrier(L, cl, cl->p); - funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ - luaC_objbarrier(L, funcstate.f, funcstate.f->source); - lexstate.buff = buff; - lexstate.dyd = dyd; - dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; - 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 */ - lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); - L->top--; /* remove scanner's table */ - return cl; /* closure is on the stack, too */ -} - diff --git a/source/external/lua/lparser.h b/source/external/lua/lparser.h index 5e4500f..a30df04 100644 --- a/source/external/lua/lparser.h +++ b/source/external/lua/lparser.h @@ -32,26 +32,36 @@ typedef enum { VKFLT, /* floating constant; nval = numerical float value */ VKINT, /* integer constant; ival = numerical integer value */ VKSTR, /* string constant; strval = TString address; - (string is fixed by the lexer) */ + (string is fixed by the scanner) */ VNONRELOC, /* expression has its value in a fixed register; info = result register */ VLOCAL, /* local variable; var.ridx = register index; var.vidx = relative index in 'actvar.arr' */ + VVARGVAR, /* vararg parameter; var.ridx = register index; + var.vidx = relative index in 'actvar.arr' */ + VGLOBAL, /* global variable; + info = relative index in 'actvar.arr' (or -1 for + implicit declaration) */ VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ VCONST, /* compile-time variable; info = absolute index in 'actvar.arr' */ VINDEXED, /* indexed variable; ind.t = table register; - ind.idx = key's R index */ + ind.idx = key's R index; + ind.ro = true if it represents a read-only global; + ind.keystr = if key is a string, index in 'k' of that string; + -1 if key is not a string */ + VVARGIND, /* indexed vararg parameter; + ind.* as in VINDEXED */ VINDEXUP, /* indexed upvalue; - ind.t = table upvalue; - ind.idx = key's K index */ + ind.idx = key's K index; + ind.* as in VINDEXED */ VINDEXI, /* indexed variable with constant integer; ind.t = table register; ind.idx = key's value */ VINDEXSTR, /* indexed variable with literal string; - ind.t = table register; - ind.idx = key's K index */ + ind.idx = key's K index; + ind.* as in VINDEXED */ VJMP, /* expression is a test/comparison; info = pc of corresponding jump instruction */ VRELOC, /* expression can put result in any register; @@ -75,10 +85,12 @@ typedef struct expdesc { struct { /* for indexed variables */ short idx; /* index (R or "long" K) */ lu_byte t; /* table (register or upvalue) */ + lu_byte ro; /* true if variable is read-only */ + int keystr; /* index in 'k' of string key, or -1 if not a string */ } ind; struct { /* for local variables */ lu_byte ridx; /* register holding the variable */ - unsigned short vidx; /* compiler index (in 'actvar.arr') */ + short vidx; /* index in 'actvar.arr' */ } var; } u; int t; /* patch list of 'exit when true' */ @@ -87,12 +99,22 @@ typedef struct expdesc { /* kinds of variables */ -#define VDKREG 0 /* regular */ -#define RDKCONST 1 /* constant */ -#define RDKTOCLOSE 2 /* to-be-closed */ -#define RDKCTC 3 /* compile-time constant */ +#define VDKREG 0 /* regular local */ +#define RDKCONST 1 /* local constant */ +#define RDKVAVAR 2 /* vararg parameter */ +#define RDKTOCLOSE 3 /* to-be-closed */ +#define RDKCTC 4 /* local compile-time constant */ +#define GDKREG 5 /* regular global */ +#define GDKCONST 6 /* global constant */ -/* description of an active local variable */ +/* variables that live in registers */ +#define varinreg(v) ((v)->vd.kind <= RDKTOCLOSE) + +/* test for global variables */ +#define varglobal(v) ((v)->vd.kind >= GDKREG) + + +/* description of an active variable */ typedef union Vardesc { struct { TValuefields; /* constant value (if it is a compile-time constant) */ @@ -111,8 +133,8 @@ typedef struct Labeldesc { TString *name; /* label identifier */ int pc; /* position in code */ int line; /* line where it appeared */ - lu_byte nactvar; /* number of active variables in that position */ - lu_byte close; /* goto that escapes upvalues */ + short nactvar; /* number of active variables in that position */ + lu_byte close; /* true for goto that escapes upvalues */ } Labeldesc; @@ -146,6 +168,7 @@ typedef struct FuncState { struct FuncState *prev; /* enclosing function */ struct LexState *ls; /* lexical state */ struct BlockCnt *bl; /* chain of current blocks */ + Table *kcache; /* cache for reusing constants */ int pc; /* next position to code (equivalent to 'ncode') */ int lasttarget; /* 'label' of last 'jump label' */ int previousline; /* last line that was saved in 'lineinfo' */ @@ -155,7 +178,7 @@ typedef struct FuncState { int firstlocal; /* index of first local var (in Dyndata array) */ int firstlabel; /* index of first label (in 'dyd->label->arr') */ short ndebugvars; /* number of elements in 'f->locvars' */ - lu_byte nactvar; /* number of active local variables */ + short nactvar; /* number of active variable declarations */ lu_byte nups; /* number of upvalues */ lu_byte freereg; /* first free register */ lu_byte iwthabs; /* instructions issued since last absolute line info */ @@ -163,7 +186,9 @@ typedef struct FuncState { } FuncState; -LUAI_FUNC int luaY_nvarstack (FuncState *fs); +LUAI_FUNC lu_byte luaY_nvarstack (FuncState *fs); +LUAI_FUNC void luaY_checklimit (FuncState *fs, int v, int l, + const char *what); LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Dyndata *dyd, const char *name, int firstchar); diff --git a/source/external/lua/lstate.c b/source/external/lua/lstate.c deleted file mode 100644 index c5e3b43..0000000 --- a/source/external/lua/lstate.c +++ /dev/null @@ -1,439 +0,0 @@ -/* -** $Id: lstate.c $ -** Global State -** See Copyright Notice in lua.h -*/ - -#define lstate_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include - -#include "lua.h" - -#include "lapi.h" -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "llex.h" -#include "lmem.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" - - - -/* -** thread state + extra space -*/ -typedef struct LX { - lu_byte extra_[LUA_EXTRASPACE]; - lua_State l; -} LX; - - -/* -** Main thread combines a thread state and the global state -*/ -typedef struct LG { - LX l; - global_State g; -} LG; - - - -#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) - - -/* -** A macro to create a "random" seed when a state is created; -** the seed is used to randomize string hashes. -*/ -#if !defined(luai_makeseed) - -#include - -/* -** Compute an initial seed with some level of randomness. -** Rely on Address Space Layout Randomization (if present) and -** current time. -*/ -#define addbuff(b,p,e) \ - { size_t t = cast_sizet(e); \ - memcpy(b + p, &t, sizeof(t)); p += sizeof(t); } - -static unsigned int luai_makeseed (lua_State *L) { - char buff[3 * sizeof(size_t)]; - unsigned int h = cast_uint(time(NULL)); - int p = 0; - addbuff(buff, p, L); /* heap variable */ - addbuff(buff, p, &h); /* local variable */ - addbuff(buff, p, &lua_newstate); /* public function */ - lua_assert(p == sizeof(buff)); - return luaS_hash(buff, p, h); -} - -#endif - - -/* -** set GCdebt to a new value keeping the value (totalbytes + GCdebt) -** invariant (and avoiding underflows in 'totalbytes') -*/ -void luaE_setdebt (global_State *g, l_mem debt) { - l_mem tb = gettotalbytes(g); - lua_assert(tb > 0); - if (debt < tb - MAX_LMEM) - debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */ - g->totalbytes = tb - debt; - g->GCdebt = debt; -} - - -LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { - UNUSED(L); UNUSED(limit); - return LUAI_MAXCCALLS; /* warning?? */ -} - - -CallInfo *luaE_extendCI (lua_State *L) { - CallInfo *ci; - lua_assert(L->ci->next == NULL); - ci = luaM_new(L, CallInfo); - lua_assert(L->ci->next == NULL); - L->ci->next = ci; - ci->previous = L->ci; - ci->next = NULL; - ci->u.l.trap = 0; - L->nci++; - return ci; -} - - -/* -** free all CallInfo structures not in use by a thread -*/ -void luaE_freeCI (lua_State *L) { - CallInfo *ci = L->ci; - CallInfo *next = ci->next; - ci->next = NULL; - while ((ci = next) != NULL) { - next = ci->next; - luaM_free(L, ci); - L->nci--; - } -} - - -/* -** free half of the CallInfo structures not in use by a thread, -** keeping the first one. -*/ -void luaE_shrinkCI (lua_State *L) { - CallInfo *ci = L->ci->next; /* first free CallInfo */ - CallInfo *next; - if (ci == NULL) - return; /* no extra elements */ - while ((next = ci->next) != NULL) { /* two extra elements? */ - CallInfo *next2 = next->next; /* next's next */ - ci->next = next2; /* remove next from the list */ - L->nci--; - luaM_free(L, next); /* free next */ - if (next2 == NULL) - break; /* no more elements */ - else { - next2->previous = ci; - ci = next2; /* continue */ - } - } -} - - -/* -** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS. -** If equal, raises an overflow error. If value is larger than -** LUAI_MAXCCALLS (which means it is handling an overflow) but -** not much larger, does not report an error (to allow overflow -** handling to work). -*/ -void luaE_checkcstack (lua_State *L) { - if (getCcalls(L) == LUAI_MAXCCALLS) - luaG_runerror(L, "C stack overflow"); - else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) - luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ -} - - -LUAI_FUNC void luaE_incCstack (lua_State *L) { - L->nCcalls++; - if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) - luaE_checkcstack(L); -} - - -static void stack_init (lua_State *L1, lua_State *L) { - int i; CallInfo *ci; - /* initialize stack array */ - L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); - L1->tbclist = L1->stack; - for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) - setnilvalue(s2v(L1->stack + i)); /* erase new stack */ - L1->top = L1->stack; - L1->stack_last = L1->stack + BASIC_STACK_SIZE; - /* initialize first ci */ - ci = &L1->base_ci; - ci->next = ci->previous = NULL; - ci->callstatus = CIST_C; - ci->func = L1->top; - ci->u.c.k = NULL; - ci->nresults = 0; - setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */ - L1->top++; - ci->top = L1->top + LUA_MINSTACK; - L1->ci = ci; -} - - -static void freestack (lua_State *L) { - if (L->stack == NULL) - return; /* stack not completely built yet */ - L->ci = &L->base_ci; /* free the entire 'ci' list */ - luaE_freeCI(L); - lua_assert(L->nci == 0); - luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */ -} - - -/* -** Create registry table and its predefined values -*/ -static void init_registry (lua_State *L, global_State *g) { - /* create registry */ - Table *registry = luaH_new(L); - sethvalue(L, &g->l_registry, registry); - luaH_resize(L, registry, LUA_RIDX_LAST, 0); - /* registry[LUA_RIDX_MAINTHREAD] = L */ - setthvalue(L, ®istry->array[LUA_RIDX_MAINTHREAD - 1], L); - /* registry[LUA_RIDX_GLOBALS] = new table (table of globals) */ - sethvalue(L, ®istry->array[LUA_RIDX_GLOBALS - 1], luaH_new(L)); -} - - -/* -** open parts of the state that may cause memory-allocation errors. -*/ -static void f_luaopen (lua_State *L, void *ud) { - global_State *g = G(L); - UNUSED(ud); - stack_init(L, L); /* init stack */ - init_registry(L, g); - luaS_init(L); - luaT_init(L); - luaX_init(L); - g->gcrunning = 1; /* allow gc */ - setnilvalue(&g->nilvalue); /* now state is complete */ - luai_userstateopen(L); -} - - -/* -** preinitialize a thread with consistent values without allocating -** any memory (to avoid errors) -*/ -static void preinit_thread (lua_State *L, global_State *g) { - G(L) = g; - L->stack = NULL; - L->ci = NULL; - L->nci = 0; - L->twups = L; /* thread has no upvalues */ - L->nCcalls = 0; - L->errorJmp = NULL; - L->hook = NULL; - L->hookmask = 0; - L->basehookcount = 0; - L->allowhook = 1; - resethookcount(L); - L->openupval = NULL; - L->status = LUA_OK; - L->errfunc = 0; - L->oldpc = 0; -} - - -static void close_state (lua_State *L) { - global_State *g = G(L); - if (!completestate(g)) /* closing a partially built state? */ - luaC_freeallobjects(L); /* jucst collect its objects */ - else { /* closing a fully built state */ - luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ - luaC_freeallobjects(L); /* collect all objects */ - luai_userstateclose(L); - } - luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); - freestack(L); - lua_assert(gettotalbytes(g) == sizeof(LG)); - (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ -} - - -LUA_API lua_State *lua_newthread (lua_State *L) { - global_State *g; - lua_State *L1; - lua_lock(L); - g = G(L); - luaC_checkGC(L); - /* create new thread */ - L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; - L1->marked = luaC_white(g); - L1->tt = LUA_VTHREAD; - /* link it on list 'allgc' */ - L1->next = g->allgc; - g->allgc = obj2gco(L1); - /* anchor it on L stack */ - setthvalue2s(L, L->top, L1); - api_incr_top(L); - preinit_thread(L1, g); - L1->hookmask = L->hookmask; - L1->basehookcount = L->basehookcount; - L1->hook = L->hook; - resethookcount(L1); - /* initialize L1 extra space */ - memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread), - LUA_EXTRASPACE); - luai_userstatethread(L, L1); - stack_init(L1, L); /* init stack */ - lua_unlock(L); - return L1; -} - - -void luaE_freethread (lua_State *L, lua_State *L1) { - LX *l = fromstate(L1); - luaF_closeupval(L1, L1->stack); /* close all upvalues */ - lua_assert(L1->openupval == NULL); - luai_userstatefree(L, L1); - freestack(L1); - luaM_free(L, l); -} - - -int luaE_resetthread (lua_State *L, int status) { - CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */ - setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */ - ci->func = L->stack; - ci->callstatus = CIST_C; - if (status == LUA_YIELD) - status = LUA_OK; - status = luaD_closeprotected(L, 1, status); - if (status != LUA_OK) /* errors? */ - luaD_seterrorobj(L, status, L->stack + 1); - else - L->top = L->stack + 1; - ci->top = L->top + LUA_MINSTACK; - L->status = cast_byte(status); - luaD_reallocstack(L, cast_int(ci->top - L->stack), 0); - return status; -} - - -LUA_API int lua_resetthread (lua_State *L) { - int status; - lua_lock(L); - status = luaE_resetthread(L, L->status); - lua_unlock(L); - return status; -} - - -LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { - int i; - lua_State *L; - global_State *g; - LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); - if (l == NULL) return NULL; - L = &l->l.l; - g = &l->g; - L->tt = LUA_VTHREAD; - g->currentwhite = bitmask(WHITE0BIT); - L->marked = luaC_white(g); - preinit_thread(L, g); - g->allgc = obj2gco(L); /* by now, only object is the main thread */ - L->next = NULL; - incnny(L); /* main thread is always non yieldable */ - g->frealloc = f; - g->ud = ud; - g->warnf = NULL; - g->ud_warn = NULL; - g->mainthread = L; - g->seed = luai_makeseed(L); - g->gcrunning = 0; /* no GC while building state */ - g->strt.size = g->strt.nuse = 0; - g->strt.hash = NULL; - setnilvalue(&g->l_registry); - g->panic = NULL; - g->gcstate = GCSpause; - g->gckind = KGC_INC; - g->gcstopem = 0; - g->gcemergency = 0; - g->finobj = g->tobefnz = g->fixedgc = NULL; - g->firstold1 = g->survival = g->old1 = g->reallyold = NULL; - g->finobjsur = g->finobjold1 = g->finobjrold = NULL; - g->sweepgc = NULL; - g->gray = g->grayagain = NULL; - g->weak = g->ephemeron = g->allweak = NULL; - g->twups = NULL; - g->totalbytes = sizeof(LG); - g->GCdebt = 0; - g->lastatomic = 0; - setivalue(&g->nilvalue, 0); /* to signal that state is not yet built */ - setgcparam(g->gcpause, LUAI_GCPAUSE); - setgcparam(g->gcstepmul, LUAI_GCMUL); - g->gcstepsize = LUAI_GCSTEPSIZE; - setgcparam(g->genmajormul, LUAI_GENMAJORMUL); - g->genminormul = LUAI_GENMINORMUL; - for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; - if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { - /* memory allocation error: free partial state */ - close_state(L); - L = NULL; - } - return L; -} - - -LUA_API void lua_close (lua_State *L) { - lua_lock(L); - L = G(L)->mainthread; /* only the main thread can be closed */ - close_state(L); -} - - -void luaE_warning (lua_State *L, const char *msg, int tocont) { - lua_WarnFunction wf = G(L)->warnf; - if (wf != NULL) - wf(G(L)->ud_warn, msg, tocont); -} - - -/* -** Generate a warning from an error message -*/ -void luaE_warnerror (lua_State *L, const char *where) { - TValue *errobj = s2v(L->top - 1); /* error object */ - const char *msg = (ttisstring(errobj)) - ? svalue(errobj) - : "error object is not a string"; - /* produce warning "error in %s (%s)" (where, msg) */ - luaE_warning(L, "error in ", 1); - luaE_warning(L, where, 1); - luaE_warning(L, " (", 1); - luaE_warning(L, msg, 1); - luaE_warning(L, ")", 0); -} - diff --git a/source/external/lua/lstate.h b/source/external/lua/lstate.h index c1283bb..20dc4d2 100644 --- a/source/external/lua/lstate.h +++ b/source/external/lua/lstate.h @@ -9,6 +9,11 @@ #include "lua.h" + +/* Some header files included here need this definition */ +typedef struct CallInfo CallInfo; + + #include "lobject.h" #include "ltm.h" #include "lzio.h" @@ -80,7 +85,7 @@ ** they must be visited again at the end of the cycle), but they are ** marked black because assignments to them must activate barriers (to ** move them back to TOUCHED1). -** - Open upvales are kept gray to avoid barriers, but they stay out +** - Open upvalues are kept gray to avoid barriers, but they stay out ** of gray lists. (They don't even have a 'gclist' field.) */ @@ -137,20 +142,32 @@ struct lua_longjmp; /* defined in ldo.c */ #define EXTRA_STACK 5 +/* +** Size of cache for strings in the API. 'N' is the number of +** sets (better be a prime) and "M" is the size of each set. +** (M == 1 makes a direct cache.) +*/ +#if !defined(STRCACHE_N) +#define STRCACHE_N 53 +#define STRCACHE_M 2 +#endif + + #define BASIC_STACK_SIZE (2*LUA_MINSTACK) -#define stacksize(th) cast_int((th)->stack_last - (th)->stack) +#define stacksize(th) cast_int((th)->stack_last.p - (th)->stack.p) /* kinds of Garbage Collection */ #define KGC_INC 0 /* incremental gc */ -#define KGC_GEN 1 /* generational gc */ +#define KGC_GENMINOR 1 /* generational gc in minor (regular) mode */ +#define KGC_GENMAJOR 2 /* generational in major mode */ typedef struct stringtable { - TString **hash; + TString **hash; /* array of buckets (linked lists of strings) */ int nuse; /* number of elements */ - int size; + int size; /* number of buckets */ } stringtable; @@ -165,18 +182,16 @@ typedef struct stringtable { ** - field 'nyield' is used only while a function is "doing" an ** yield (from the yield until the next resume); ** - field 'nres' is used only while closing tbc variables when -** returning from a C function; -** - field 'transferinfo' is used only during call/returnhooks, -** before the function starts or after it ends. +** returning from a function; */ -typedef struct CallInfo { - StkId func; /* function index in the stack */ - StkId top; /* top for this function */ +struct CallInfo { + StkIdRel func; /* function index in the stack */ + StkIdRel top; /* top for this function */ struct CallInfo *previous, *next; /* dynamic call link */ union { struct { /* only for Lua functions */ const Instruction *savedpc; - volatile l_signalT trap; + volatile l_signalT trap; /* function is tracing lines/counts */ int nextraargs; /* # of extra arguments in vararg functions */ } l; struct { /* only for C functions */ @@ -189,35 +204,54 @@ typedef struct CallInfo { int funcidx; /* called-function index */ int nyield; /* number of values yielded */ int nres; /* number of values returned */ - struct { /* info about transferred values (for call/return hooks) */ - unsigned short ftransfer; /* offset of first value transferred */ - unsigned short ntransfer; /* number of values transferred */ - } transferinfo; } u2; - short nresults; /* expected number of results from this function */ - unsigned short callstatus; -} CallInfo; + l_uint32 callstatus; +}; + + +/* +** Maximum expected number of results from a function +** (must fit in CIST_NRESULTS). +*/ +#define MAXRESULTS 250 /* ** Bits in CallInfo status */ -#define CIST_OAH (1<<0) /* original value of 'allowhook' */ -#define CIST_C (1<<1) /* call is running a C function */ -#define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ -#define CIST_HOOKED (1<<3) /* call is running a debug hook */ -#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */ -#define CIST_TAIL (1<<5) /* call was tail called */ -#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ -#define CIST_FIN (1<<7) /* call is running a finalizer */ -#define CIST_TRAN (1<<8) /* 'ci' has transfer information */ -#define CIST_CLSRET (1<<9) /* function is closing tbc variables */ -/* Bits 10-12 are used for CIST_RECST (see below) */ -#define CIST_RECST 10 -#if defined(LUA_COMPAT_LT_LE) -#define CIST_LEQ (1<<13) /* using __lt for __le */ -#endif +/* bits 0-7 are the expected number of results from this function + 1 */ +#define CIST_NRESULTS 0xffu +/* bits 8-11 count call metamethods (and their extra arguments) */ +#define CIST_CCMT 8 /* the offset, not the mask */ +#define MAX_CCMT (0xfu << CIST_CCMT) + +/* Bits 12-14 are used for CIST_RECST (see below) */ +#define CIST_RECST 12 /* the offset, not the mask */ + +/* call is running a C function (still in first 16 bits) */ +#define CIST_C (1u << (CIST_RECST + 3)) +/* call is on a fresh "luaV_execute" frame */ +#define CIST_FRESH (cast(l_uint32, CIST_C) << 1) +/* function is closing tbc variables */ +#define CIST_CLSRET (CIST_FRESH << 1) +/* function has tbc variables to close */ +#define CIST_TBC (CIST_CLSRET << 1) +/* original value of 'allowhook' */ +#define CIST_OAH (CIST_TBC << 1) +/* call is running a debug hook */ +#define CIST_HOOKED (CIST_OAH << 1) +/* doing a yieldable protected call */ +#define CIST_YPCALL (CIST_HOOKED << 1) +/* call was tail called */ +#define CIST_TAIL (CIST_YPCALL << 1) +/* last hook called yielded */ +#define CIST_HOOKYIELD (CIST_TAIL << 1) +/* function "called" a finalizer */ +#define CIST_FIN (CIST_HOOKYIELD << 1) + + +#define get_nresults(cs) (cast_int((cs) & CIST_NRESULTS) - 1) /* ** Field CIST_RECST stores the "recover status", used to keep the error @@ -228,8 +262,8 @@ typedef struct CallInfo { #define getcistrecst(ci) (((ci)->callstatus >> CIST_RECST) & 7) #define setcistrecst(ci,st) \ check_exp(((st) & 7) == (st), /* status must fit in three bits */ \ - ((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \ - | ((st) << CIST_RECST))) + ((ci)->callstatus = ((ci)->callstatus & ~(7u << CIST_RECST)) \ + | (cast(l_uint32, st) << CIST_RECST))) /* active function is a Lua function */ @@ -238,9 +272,53 @@ typedef struct CallInfo { /* call is running Lua code (not a hook) */ #define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED))) -/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ -#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) -#define getoah(st) ((st) & CIST_OAH) + +#define setoah(ci,v) \ + ((ci)->callstatus = ((v) ? (ci)->callstatus | CIST_OAH \ + : (ci)->callstatus & ~CIST_OAH)) +#define getoah(ci) (((ci)->callstatus & CIST_OAH) ? 1 : 0) + + +/* +** 'per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte allowhook; + TStatus status; + StkIdRel top; /* first free slot in the stack */ + struct global_State *l_G; + CallInfo *ci; /* call info for current function */ + StkIdRel stack_last; /* end of stack (last element + 1) */ + StkIdRel stack; /* stack base */ + UpVal *openupval; /* list of open upvalues in this stack */ + StkIdRel tbclist; /* list of to-be-closed variables */ + GCObject *gclist; + struct lua_State *twups; /* list of threads with open upvalues */ + struct lua_longjmp *errorJmp; /* current error recover point */ + CallInfo base_ci; /* CallInfo for first level (C host) */ + volatile lua_Hook hook; + ptrdiff_t errfunc; /* current error handling function (stack index) */ + l_uint32 nCcalls; /* number of nested non-yieldable or C calls */ + int oldpc; /* last pc traced */ + int nci; /* number of items in 'ci' list */ + int basehookcount; + int hookcount; + volatile l_signalT hookmask; + struct { /* info about transferred values (for call/return hooks) */ + int ftransfer; /* offset of first value transferred */ + int ntransfer; /* number of values transferred */ + } transferinfo; +}; + + +/* +** thread state + extra space +*/ +typedef struct LX { + lu_byte extra_[LUA_EXTRASPACE]; + lua_State l; +} LX; /* @@ -249,25 +327,21 @@ typedef struct CallInfo { typedef struct global_State { lua_Alloc frealloc; /* function to reallocate memory */ void *ud; /* auxiliary data to 'frealloc' */ - l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ - l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ - lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ - lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */ + l_mem GCtotalbytes; /* number of bytes currently allocated + debt */ + l_mem GCdebt; /* bytes counted but not yet allocated */ + l_mem GCmarked; /* number of objects marked in a GC cycle */ + l_mem GCmajorminor; /* auxiliary counter to control major-minor shifts */ stringtable strt; /* hash table for strings */ TValue l_registry; TValue nilvalue; /* a nil value */ unsigned int seed; /* randomized seed for hashes */ + lu_byte gcparams[LUA_GCPN]; lu_byte currentwhite; lu_byte gcstate; /* state of garbage collector */ lu_byte gckind; /* kind of GC running */ lu_byte gcstopem; /* stops emergency collections */ - lu_byte genminormul; /* control for minor generational collections */ - lu_byte genmajormul; /* control for major generational collections */ - lu_byte gcrunning; /* true if GC is running */ + lu_byte gcstp; /* control whether GC is running */ lu_byte gcemergency; /* true if this is an emergency collection */ - lu_byte gcpause; /* size of pause between successive GCs */ - lu_byte gcstepmul; /* GC "speed" */ - lu_byte gcstepsize; /* (log2 of) GC granularity */ GCObject *allgc; /* list of all collectable objects */ GCObject **sweepgc; /* current position of sweep in list */ GCObject *finobj; /* list of collectable objects with finalizers */ @@ -288,46 +362,18 @@ typedef struct global_State { GCObject *finobjrold; /* list of really old objects with finalizers */ struct lua_State *twups; /* list of threads with open upvalues */ lua_CFunction panic; /* to be called in unprotected errors */ - struct lua_State *mainthread; TString *memerrmsg; /* message for memory-allocation errors */ TString *tmname[TM_N]; /* array with tag-method names */ - struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ + struct Table *mt[LUA_NUMTYPES]; /* metatables for basic types */ TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ lua_WarnFunction warnf; /* warning function */ void *ud_warn; /* auxiliary data to 'warnf' */ + LX mainth; /* main thread of this state */ } global_State; -/* -** 'per thread' state -*/ -struct lua_State { - CommonHeader; - lu_byte status; - lu_byte allowhook; - unsigned short nci; /* number of items in 'ci' list */ - StkId top; /* first free slot in the stack */ - global_State *l_G; - CallInfo *ci; /* call info for current function */ - StkId stack_last; /* end of stack (last element + 1) */ - StkId stack; /* stack base */ - UpVal *openupval; /* list of open upvalues in this stack */ - StkId tbclist; /* list of to-be-closed variables */ - GCObject *gclist; - struct lua_State *twups; /* list of threads with open upvalues */ - struct lua_longjmp *errorJmp; /* current error recover point */ - CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ - volatile lua_Hook hook; - ptrdiff_t errfunc; /* current error handling function (stack index) */ - l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ - int oldpc; /* last pc traced */ - int basehookcount; - int hookcount; - volatile l_signalT hookmask; -}; - - #define G(L) (L->l_G) +#define mainthread(G) (&(G)->mainth.l) /* ** 'g->nilvalue' being a nil value flags that the state was completely @@ -380,24 +426,25 @@ union GCUnion { /* ** macro to convert a Lua object into a GCObject -** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.) */ -#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc)) +#define obj2gco(v) \ + check_exp(novariant((v)->tt) >= LUA_TSTRING, &(cast_u(v)->gc)) -/* actual number of total bytes allocated */ -#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) +/* actual number of total memory allocated */ +#define gettotalbytes(g) ((g)->GCtotalbytes - (g)->GCdebt) + LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC lu_mem luaE_threadsize (lua_State *L); LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); -LUAI_FUNC void luaE_freeCI (lua_State *L); LUAI_FUNC void luaE_shrinkCI (lua_State *L); LUAI_FUNC void luaE_checkcstack (lua_State *L); LUAI_FUNC void luaE_incCstack (lua_State *L); LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); -LUAI_FUNC int luaE_resetthread (lua_State *L, int status); +LUAI_FUNC TStatus luaE_resetthread (lua_State *L, TStatus status); #endif diff --git a/source/external/lua/lstring.c b/source/external/lua/lstring.c deleted file mode 100644 index 13dcaf4..0000000 --- a/source/external/lua/lstring.c +++ /dev/null @@ -1,273 +0,0 @@ -/* -** $Id: lstring.c $ -** String table (keeps all strings handled by Lua) -** See Copyright Notice in lua.h -*/ - -#define lstring_c -#define LUA_CORE - -#include "lprefix.h" - - -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" - - -/* -** Maximum size for string table. -*/ -#define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) - - -/* -** equality for long strings -*/ -int luaS_eqlngstr (TString *a, TString *b) { - size_t len = a->u.lnglen; - lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); - return (a == b) || /* same instance or... */ - ((len == b->u.lnglen) && /* equal length and ... */ - (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ -} - - -unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { - unsigned int h = seed ^ cast_uint(l); - for (; l > 0; l--) - h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); - return h; -} - - -unsigned int luaS_hashlongstr (TString *ts) { - lua_assert(ts->tt == LUA_VLNGSTR); - if (ts->extra == 0) { /* no hash? */ - size_t len = ts->u.lnglen; - ts->hash = luaS_hash(getstr(ts), len, ts->hash); - ts->extra = 1; /* now it has its hash */ - } - return ts->hash; -} - - -static void tablerehash (TString **vect, int osize, int nsize) { - int i; - for (i = osize; i < nsize; i++) /* clear new elements */ - vect[i] = NULL; - for (i = 0; i < osize; i++) { /* rehash old part of the array */ - TString *p = vect[i]; - vect[i] = NULL; - while (p) { /* for each string in the list */ - TString *hnext = p->u.hnext; /* save next */ - unsigned int h = lmod(p->hash, nsize); /* new position */ - p->u.hnext = vect[h]; /* chain it into array */ - vect[h] = p; - p = hnext; - } - } -} - - -/* -** Resize the string table. If allocation fails, keep the current size. -** (This can degrade performance, but any non-zero size should work -** correctly.) -*/ -void luaS_resize (lua_State *L, int nsize) { - stringtable *tb = &G(L)->strt; - int osize = tb->size; - TString **newvect; - if (nsize < osize) /* shrinking table? */ - tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */ - newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*); - if (l_unlikely(newvect == NULL)) { /* reallocation failed? */ - if (nsize < osize) /* was it shrinking table? */ - tablerehash(tb->hash, nsize, osize); /* restore to original size */ - /* leave table as it was */ - } - else { /* allocation succeeded */ - tb->hash = newvect; - tb->size = nsize; - if (nsize > osize) - tablerehash(newvect, osize, nsize); /* rehash for new size */ - } -} - - -/* -** Clear API string cache. (Entries cannot be empty, so fill them with -** a non-collectable string.) -*/ -void luaS_clearcache (global_State *g) { - int i, j; - for (i = 0; i < STRCACHE_N; i++) - for (j = 0; j < STRCACHE_M; j++) { - if (iswhite(g->strcache[i][j])) /* will entry be collected? */ - g->strcache[i][j] = 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, j; - stringtable *tb = &G(L)->strt; - tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*); - tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */ - tb->size = MINSTRTABSIZE; - /* 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_N; i++) /* fill cache with valid strings */ - for (j = 0; j < STRCACHE_M; j++) - g->strcache[i][j] = g->memerrmsg; -} - - - -/* -** creates a new string object -*/ -static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { - TString *ts; - GCObject *o; - size_t totalsize; /* total size of TString object */ - totalsize = sizelstring(l); - o = luaC_newobj(L, tag, totalsize); - ts = gco2ts(o); - ts->hash = h; - ts->extra = 0; - getstr(ts)[l] = '\0'; /* ending 0 */ - return ts; -} - - -TString *luaS_createlngstrobj (lua_State *L, size_t l) { - TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); - ts->u.lnglen = l; - return ts; -} - - -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)->u.hnext; - *p = (*p)->u.hnext; /* remove element from its list */ - tb->nuse--; -} - - -static void growstrtab (lua_State *L, stringtable *tb) { - if (l_unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ - luaC_fullgc(L, 1); /* try to free some... */ - if (tb->nuse == MAX_INT) /* still too many? */ - luaM_error(L); /* cannot even create a message... */ - } - if (tb->size <= MAXSTRTB / 2) /* can grow string table? */ - luaS_resize(L, tb->size * 2); -} - - -/* -** Checks whether short string exists and reuses it or creates a new one. -*/ -static TString *internshrstr (lua_State *L, const char *str, size_t l) { - TString *ts; - global_State *g = G(L); - stringtable *tb = &g->strt; - unsigned int h = luaS_hash(str, l, g->seed); - TString **list = &tb->hash[lmod(h, tb->size)]; - lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ - 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)? */ - changewhite(ts); /* resurrect it */ - return ts; - } - } - /* else must create a new string */ - if (tb->nuse >= tb->size) { /* need to grow string table? */ - growstrtab(L, tb); - list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ - } - ts = createstrobj(L, l, LUA_VSHRSTR, h); - memcpy(getstr(ts), str, l * sizeof(char)); - ts->shrlen = cast_byte(l); - ts->u.hnext = *list; - *list = ts; - tb->nuse++; - return ts; -} - - -/* -** new string (with explicit length) -*/ -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_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) - luaM_toobig(L); - ts = luaS_createlngstrobj(L, l); - memcpy(getstr(ts), str, l * sizeof(char)); - return ts; - } -} - - -/* -** 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) { - unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ - int j; - TString **p = G(L)->strcache[i]; - for (j = 0; j < STRCACHE_M; j++) { - if (strcmp(str, getstr(p[j])) == 0) /* hit? */ - return p[j]; /* that is it */ - } - /* normal route */ - for (j = STRCACHE_M - 1; j > 0; j--) - p[j] = p[j - 1]; /* move out last element */ - /* new element is first in the list */ - p[0] = luaS_newlstr(L, str, strlen(str)); - return p[0]; -} - - -Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) { - Udata *u; - int i; - GCObject *o; - if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) - luaM_toobig(L); - o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s)); - u = gco2u(o); - u->len = s; - u->nuvalue = nuvalue; - u->metatable = NULL; - for (i = 0; i < nuvalue; i++) - setnilvalue(&u->uv[i].uv); - return u; -} - diff --git a/source/external/lua/lstring.h b/source/external/lua/lstring.h index 450c239..1643c3d 100644 --- a/source/external/lua/lstring.h +++ b/source/external/lua/lstring.h @@ -20,10 +20,23 @@ /* -** Size of a TString: Size of the header plus space for the string +** 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 + + +/* +** Size of a short TString: Size of the header plus space for the string ** itself (including final '\0'). */ -#define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) +#define sizestrshr(l) \ + (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) + #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ (sizeof(s)/sizeof(char))-1)) @@ -32,7 +45,7 @@ /* ** test whether a string is a reserved word */ -#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) +#define isreserved(s) (strisshr(s) && (s)->extra > 0) /* @@ -41,17 +54,20 @@ #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) -LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); -LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); -LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC unsigned luaS_hashlongstr (TString *ts); +LUAI_FUNC int luaS_eqstr (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, int nuvalue); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, + unsigned short nuvalue); LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); - +LUAI_FUNC TString *luaS_newextlstr (lua_State *L, + const char *s, size_t len, lua_Alloc falloc, void *ud); +LUAI_FUNC size_t luaS_sizelngstr (size_t len, int kind); +LUAI_FUNC TString *luaS_normstr (lua_State *L, TString *ts); #endif diff --git a/source/external/lua/lstrlib.c b/source/external/lua/lstrlib.c deleted file mode 100644 index 47e5b27..0000000 --- a/source/external/lua/lstrlib.c +++ /dev/null @@ -1,1817 +0,0 @@ -/* -** $Id: lstrlib.c $ -** Standard library for string operations and pattern-matching -** See Copyright Notice in lua.h -*/ - -#define lstrlib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* -** maximum number of captures that a pattern can do during -** pattern-matching. This limit is arbitrary, but must fit in -** an unsigned char. -*/ -#if !defined(LUA_MAXCAPTURES) -#define LUA_MAXCAPTURES 32 -#endif - - -/* macro to 'unsign' a character */ -#define uchar(c) ((unsigned char)(c)) - - -/* -** Some sizes are better limited to fit in 'int', but must also fit in -** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.) -*/ -#define MAX_SIZET ((size_t)(~(size_t)0)) - -#define MAXSIZE \ - (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX)) - - - - -static int str_len (lua_State *L) { - size_t l; - luaL_checklstring(L, 1, &l); - lua_pushinteger(L, (lua_Integer)l); - return 1; -} - - -/* -** translate a relative initial string position -** (negative means back from end): clip result to [1, inf). -** The length of any string in Lua must fit in a lua_Integer, -** so there are no overflows in the casts. -** The inverted comparison avoids a possible overflow -** computing '-pos'. -*/ -static size_t posrelatI (lua_Integer pos, size_t len) { - if (pos > 0) - return (size_t)pos; - else if (pos == 0) - return 1; - else if (pos < -(lua_Integer)len) /* inverted comparison */ - return 1; /* clip to 1 */ - else return len + (size_t)pos + 1; -} - - -/* -** Gets an optional ending string position from argument 'arg', -** with default value 'def'. -** Negative means back from end: clip result to [0, len] -*/ -static size_t getendpos (lua_State *L, int arg, lua_Integer def, - size_t len) { - lua_Integer pos = luaL_optinteger(L, arg, def); - if (pos > (lua_Integer)len) - return len; - else if (pos >= 0) - return (size_t)pos; - else if (pos < -(lua_Integer)len) - return 0; - else return len + (size_t)pos + 1; -} - - -static int str_sub (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - size_t start = posrelatI(luaL_checkinteger(L, 2), l); - size_t end = getendpos(L, 3, -1, l); - if (start <= end) - lua_pushlstring(L, s + start - 1, (end - start) + 1); - else lua_pushliteral(L, ""); - return 1; -} - - -static int str_reverse (lua_State *L) { - size_t l, i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - char *p = luaL_buffinitsize(L, &b, l); - for (i = 0; i < l; i++) - p[i] = s[l - i - 1]; - luaL_pushresultsize(&b, l); - return 1; -} - - -static int str_lower (lua_State *L) { - size_t l; - size_t i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - char *p = luaL_buffinitsize(L, &b, l); - for (i=0; i MAXSIZE / n)) - return luaL_error(L, "resulting string too large"); - else { - size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep; - luaL_Buffer b; - char *p = luaL_buffinitsize(L, &b, totallen); - while (n-- > 1) { /* first n-1 copies (followed by separator) */ - memcpy(p, s, l * sizeof(char)); p += l; - if (lsep > 0) { /* empty 'memcpy' is not that cheap */ - memcpy(p, sep, lsep * sizeof(char)); - p += lsep; - } - } - memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ - luaL_pushresultsize(&b, totallen); - } - return 1; -} - - -static int str_byte (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - lua_Integer pi = luaL_optinteger(L, 2, 1); - size_t posi = posrelatI(pi, l); - size_t pose = getendpos(L, 3, pi, l); - int n, i; - if (posi > pose) return 0; /* empty interval; return no values */ - if (l_unlikely(pose - posi >= (size_t)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; iinit) { - state->init = 1; - luaL_buffinit(L, &state->B); - } - luaL_addlstring(&state->B, (const char *)b, size); - return 0; -} - - -static int str_dump (lua_State *L) { - struct str_Writer state; - int strip = lua_toboolean(L, 2); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, 1); /* ensure function is on the top of the stack */ - state.init = 0; - if (l_unlikely(lua_dump(L, writer, &state, strip) != 0)) - return luaL_error(L, "unable to dump given function"); - luaL_pushresult(&state.B); - return 1; -} - - - -/* -** {====================================================== -** METAMETHODS -** ======================================================= -*/ - -#if defined(LUA_NOCVTS2N) /* { */ - -/* no coercion from strings to numbers */ - -static const luaL_Reg stringmetamethods[] = { - {"__index", NULL}, /* placeholder */ - {NULL, NULL} -}; - -#else /* }{ */ - -static int tonum (lua_State *L, int arg) { - if (lua_type(L, arg) == LUA_TNUMBER) { /* already a number? */ - lua_pushvalue(L, arg); - return 1; - } - else { /* check whether it is a numerical string */ - size_t len; - const char *s = lua_tolstring(L, arg, &len); - return (s != NULL && lua_stringtonumber(L, s) == len + 1); - } -} - - -static void trymt (lua_State *L, const char *mtname) { - lua_settop(L, 2); /* back to the original arguments */ - if (l_unlikely(lua_type(L, 2) == LUA_TSTRING || - !luaL_getmetafield(L, 2, mtname))) - luaL_error(L, "attempt to %s a '%s' with a '%s'", mtname + 2, - luaL_typename(L, -2), luaL_typename(L, -1)); - lua_insert(L, -3); /* put metamethod before arguments */ - lua_call(L, 2, 1); /* call metamethod */ -} - - -static int arith (lua_State *L, int op, const char *mtname) { - if (tonum(L, 1) && tonum(L, 2)) - lua_arith(L, op); /* result will be on the top */ - else - trymt(L, mtname); - return 1; -} - - -static int arith_add (lua_State *L) { - return arith(L, LUA_OPADD, "__add"); -} - -static int arith_sub (lua_State *L) { - return arith(L, LUA_OPSUB, "__sub"); -} - -static int arith_mul (lua_State *L) { - return arith(L, LUA_OPMUL, "__mul"); -} - -static int arith_mod (lua_State *L) { - return arith(L, LUA_OPMOD, "__mod"); -} - -static int arith_pow (lua_State *L) { - return arith(L, LUA_OPPOW, "__pow"); -} - -static int arith_div (lua_State *L) { - return arith(L, LUA_OPDIV, "__div"); -} - -static int arith_idiv (lua_State *L) { - return arith(L, LUA_OPIDIV, "__idiv"); -} - -static int arith_unm (lua_State *L) { - return arith(L, LUA_OPUNM, "__unm"); -} - - -static const luaL_Reg stringmetamethods[] = { - {"__add", arith_add}, - {"__sub", arith_sub}, - {"__mul", arith_mul}, - {"__mod", arith_mod}, - {"__pow", arith_pow}, - {"__div", arith_div}, - {"__idiv", arith_idiv}, - {"__unm", arith_unm}, - {"__index", NULL}, /* placeholder */ - {NULL, NULL} -}; - -#endif /* } */ - -/* }====================================================== */ - -/* -** {====================================================== -** PATTERN MATCHING -** ======================================================= -*/ - - -#define CAP_UNFINISHED (-1) -#define CAP_POSITION (-2) - - -typedef struct MatchState { - const char *src_init; /* init of source string */ - const char *src_end; /* end ('\0') of source string */ - const char *p_end; /* end ('\0') of pattern */ - lua_State *L; - int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ - unsigned char level; /* total number of captures (finished or unfinished) */ - struct { - const char *init; - ptrdiff_t len; - } capture[LUA_MAXCAPTURES]; -} MatchState; - - -/* recursive function */ -static const char *match (MatchState *ms, const char *s, const char *p); - - -/* maximum recursion depth for 'match' */ -#if !defined(MAXCCALLS) -#define MAXCCALLS 200 -#endif - - -#define L_ESC '%' -#define SPECIALS "^$*+?.([%-" - - -static int check_capture (MatchState *ms, int l) { - l -= '1'; - if (l_unlikely(l < 0 || l >= ms->level || - ms->capture[l].len == CAP_UNFINISHED)) - return luaL_error(ms->L, "invalid capture index %%%d", l + 1); - return l; -} - - -static int capture_to_close (MatchState *ms) { - int level = ms->level; - for (level--; level>=0; level--) - if (ms->capture[level].len == CAP_UNFINISHED) return level; - return luaL_error(ms->L, "invalid pattern capture"); -} - - -static const char *classend (MatchState *ms, const char *p) { - switch (*p++) { - case L_ESC: { - if (l_unlikely(p == ms->p_end)) - luaL_error(ms->L, "malformed pattern (ends with '%%')"); - return p+1; - } - case '[': { - if (*p == '^') p++; - do { /* look for a ']' */ - if (l_unlikely(p == ms->p_end)) - luaL_error(ms->L, "malformed pattern (missing ']')"); - if (*(p++) == L_ESC && p < ms->p_end) - p++; /* skip escapes (e.g. '%]') */ - } while (*p != ']'); - return p+1; - } - default: { - return p; - } - } -} - - -static int match_class (int c, int cl) { - int res; - switch (tolower(cl)) { - case 'a' : res = isalpha(c); break; - case 'c' : res = iscntrl(c); break; - case 'd' : res = isdigit(c); break; - case 'g' : res = isgraph(c); break; - case 'l' : res = islower(c); break; - case 'p' : res = ispunct(c); break; - case 's' : res = isspace(c); break; - case 'u' : res = isupper(c); break; - case 'w' : res = isalnum(c); break; - case 'x' : res = isxdigit(c); break; - case 'z' : res = (c == 0); break; /* deprecated option */ - default: return (cl == c); - } - return (islower(cl) ? res : !res); -} - - -static int matchbracketclass (int c, const char *p, const char *ec) { - int sig = 1; - if (*(p+1) == '^') { - sig = 0; - p++; /* skip the '^' */ - } - while (++p < ec) { - if (*p == L_ESC) { - p++; - if (match_class(c, uchar(*p))) - return sig; - } - else if ((*(p+1) == '-') && (p+2 < ec)) { - p+=2; - if (uchar(*(p-2)) <= c && c <= uchar(*p)) - return sig; - } - else if (uchar(*p) == c) return sig; - } - return !sig; -} - - -static int singlematch (MatchState *ms, const char *s, const char *p, - const char *ep) { - if (s >= ms->src_end) - return 0; - else { - int c = uchar(*s); - switch (*p) { - case '.': return 1; /* matches any char */ - case L_ESC: return match_class(c, uchar(*(p+1))); - case '[': return matchbracketclass(c, p, ep-1); - default: return (uchar(*p) == c); - } - } -} - - -static const char *matchbalance (MatchState *ms, const char *s, - const char *p) { - if (l_unlikely(p >= ms->p_end - 1)) - luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')"); - if (*s != *p) return NULL; - else { - int b = *p; - int e = *(p+1); - int cont = 1; - while (++s < ms->src_end) { - if (*s == e) { - if (--cont == 0) return s+1; - } - else if (*s == b) cont++; - } - } - return NULL; /* string ends out of balance */ -} - - -static const char *max_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - ptrdiff_t i = 0; /* counts maximum expand for item */ - while (singlematch(ms, s + i, p, ep)) - i++; - /* keeps trying to match with the maximum repetitions */ - while (i>=0) { - const char *res = match(ms, (s+i), ep+1); - if (res) return res; - i--; /* else didn't match; reduce 1 repetition to try again */ - } - return NULL; -} - - -static const char *min_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - for (;;) { - const char *res = match(ms, s, ep+1); - if (res != NULL) - return res; - else if (singlematch(ms, s, p, ep)) - s++; /* try with one more repetition */ - else return NULL; - } -} - - -static const char *start_capture (MatchState *ms, const char *s, - const char *p, int what) { - const char *res; - int level = ms->level; - if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); - ms->capture[level].init = s; - ms->capture[level].len = what; - ms->level = level+1; - if ((res=match(ms, s, p)) == NULL) /* match failed? */ - ms->level--; /* undo capture */ - return res; -} - - -static const char *end_capture (MatchState *ms, const char *s, - const char *p) { - int l = capture_to_close(ms); - const char *res; - ms->capture[l].len = s - ms->capture[l].init; /* close capture */ - if ((res = match(ms, s, p)) == NULL) /* match failed? */ - ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ - return res; -} - - -static const char *match_capture (MatchState *ms, const char *s, int l) { - size_t len; - l = check_capture(ms, l); - len = ms->capture[l].len; - if ((size_t)(ms->src_end-s) >= len && - memcmp(ms->capture[l].init, s, len) == 0) - return s+len; - else return NULL; -} - - -static const char *match (MatchState *ms, const char *s, const char *p) { - if (l_unlikely(ms->matchdepth-- == 0)) - luaL_error(ms->L, "pattern too complex"); - init: /* using goto's to optimize tail recursion */ - if (p != ms->p_end) { /* end of pattern? */ - switch (*p) { - case '(': { /* start capture */ - if (*(p + 1) == ')') /* position capture? */ - s = start_capture(ms, s, p + 2, CAP_POSITION); - else - s = start_capture(ms, s, p + 1, CAP_UNFINISHED); - break; - } - case ')': { /* end capture */ - s = end_capture(ms, s, p + 1); - break; - } - case '$': { - if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */ - goto dflt; /* no; go to default */ - s = (s == ms->src_end) ? s : NULL; /* check end of string */ - break; - } - case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ - switch (*(p + 1)) { - case 'b': { /* balanced string? */ - s = matchbalance(ms, s, p + 2); - if (s != NULL) { - p += 4; goto init; /* return match(ms, s, p + 4); */ - } /* else fail (s == NULL) */ - break; - } - case 'f': { /* frontier? */ - const char *ep; char previous; - p += 2; - if (l_unlikely(*p != '[')) - luaL_error(ms->L, "missing '[' after '%%f' in pattern"); - ep = classend(ms, p); /* points to what is next */ - previous = (s == ms->src_init) ? '\0' : *(s - 1); - if (!matchbracketclass(uchar(previous), p, ep - 1) && - matchbracketclass(uchar(*s), p, ep - 1)) { - p = ep; goto init; /* return match(ms, s, ep); */ - } - s = NULL; /* match failed */ - break; - } - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case '8': case '9': { /* capture results (%0-%9)? */ - s = match_capture(ms, s, uchar(*(p + 1))); - if (s != NULL) { - p += 2; goto init; /* return match(ms, s, p + 2) */ - } - break; - } - default: goto dflt; - } - break; - } - default: dflt: { /* pattern class plus optional suffix */ - const char *ep = classend(ms, p); /* points to optional suffix */ - /* does not match at least once? */ - if (!singlematch(ms, s, p, ep)) { - if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ - p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ - } - else /* '+' or no suffix */ - s = NULL; /* fail */ - } - else { /* matched once */ - switch (*ep) { /* handle optional suffix */ - case '?': { /* optional */ - const char *res; - if ((res = match(ms, s + 1, ep + 1)) != NULL) - s = res; - else { - p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ - } - break; - } - case '+': /* 1 or more repetitions */ - s++; /* 1 match already done */ - /* FALLTHROUGH */ - case '*': /* 0 or more repetitions */ - s = max_expand(ms, s, p, ep); - break; - case '-': /* 0 or more repetitions (minimum) */ - s = min_expand(ms, s, p, ep); - break; - default: /* no suffix */ - s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ - } - } - break; - } - } - } - ms->matchdepth++; - return s; -} - - - -static const char *lmemfind (const char *s1, size_t l1, - const char *s2, size_t l2) { - if (l2 == 0) return s1; /* empty strings are everywhere */ - else if (l2 > l1) return NULL; /* avoids a negative 'l1' */ - else { - const char *init; /* to search for a '*s2' inside 's1' */ - l2--; /* 1st char will be checked by 'memchr' */ - l1 = l1-l2; /* 's2' cannot be found after that */ - while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { - init++; /* 1st char is already checked */ - if (memcmp(init, s2+1, l2) == 0) - return init-1; - else { /* correct 'l1' and 's1' to try again */ - l1 -= init-s1; - s1 = init; - } - } - return NULL; /* not found */ - } -} - - -/* -** get information about the i-th capture. If there are no captures -** and 'i==0', return information about the whole match, which -** is the range 's'..'e'. If the capture is a string, return -** its length and put its address in '*cap'. If it is an integer -** (a position), push it on the stack and return CAP_POSITION. -*/ -static size_t get_onecapture (MatchState *ms, int i, const char *s, - const char *e, const char **cap) { - if (i >= ms->level) { - if (l_unlikely(i != 0)) - luaL_error(ms->L, "invalid capture index %%%d", i + 1); - *cap = s; - return e - s; - } - else { - ptrdiff_t capl = ms->capture[i].len; - *cap = ms->capture[i].init; - if (l_unlikely(capl == CAP_UNFINISHED)) - luaL_error(ms->L, "unfinished capture"); - else if (capl == CAP_POSITION) - lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1); - return capl; - } -} - - -/* -** Push the i-th capture on the stack. -*/ -static void push_onecapture (MatchState *ms, int i, const char *s, - const char *e) { - const char *cap; - ptrdiff_t l = get_onecapture(ms, i, s, e, &cap); - if (l != CAP_POSITION) - lua_pushlstring(ms->L, cap, l); - /* else position was already pushed */ -} - - -static int push_captures (MatchState *ms, const char *s, const char *e) { - int i; - int nlevels = (ms->level == 0 && s) ? 1 : ms->level; - luaL_checkstack(ms->L, nlevels, "too many captures"); - for (i = 0; i < nlevels; i++) - push_onecapture(ms, i, s, e); - return nlevels; /* number of strings pushed */ -} - - -/* check whether pattern has no special characters */ -static int nospecials (const char *p, size_t l) { - size_t upto = 0; - do { - if (strpbrk(p + upto, SPECIALS)) - return 0; /* pattern has a special character */ - upto += strlen(p + upto) + 1; /* may have more after \0 */ - } while (upto <= l); - return 1; /* no special chars found */ -} - - -static void prepstate (MatchState *ms, lua_State *L, - const char *s, size_t ls, const char *p, size_t lp) { - ms->L = L; - ms->matchdepth = MAXCCALLS; - ms->src_init = s; - ms->src_end = s + ls; - ms->p_end = p + lp; -} - - -static void reprepstate (MatchState *ms) { - ms->level = 0; - lua_assert(ms->matchdepth == MAXCCALLS); -} - - -static int str_find_aux (lua_State *L, int find) { - size_t ls, lp; - const char *s = luaL_checklstring(L, 1, &ls); - const char *p = luaL_checklstring(L, 2, &lp); - size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; - if (init > ls) { /* start after string's end? */ - luaL_pushfail(L); /* cannot find anything */ - return 1; - } - /* explicit request or no special characters? */ - if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { - /* do a plain search */ - const char *s2 = lmemfind(s + init, ls - init, p, lp); - if (s2) { - lua_pushinteger(L, (s2 - s) + 1); - lua_pushinteger(L, (s2 - s) + lp); - return 2; - } - } - else { - MatchState ms; - const char *s1 = s + init; - int anchor = (*p == '^'); - if (anchor) { - p++; lp--; /* skip anchor character */ - } - prepstate(&ms, L, s, ls, p, lp); - do { - const char *res; - reprepstate(&ms); - if ((res=match(&ms, s1, p)) != NULL) { - if (find) { - lua_pushinteger(L, (s1 - s) + 1); /* start */ - lua_pushinteger(L, res - s); /* end */ - return push_captures(&ms, NULL, 0) + 2; - } - else - return push_captures(&ms, s1, res); - } - } while (s1++ < ms.src_end && !anchor); - } - luaL_pushfail(L); /* not found */ - return 1; -} - - -static int str_find (lua_State *L) { - return str_find_aux(L, 1); -} - - -static int str_match (lua_State *L) { - return str_find_aux(L, 0); -} - - -/* state for 'gmatch' */ -typedef struct GMatchState { - const char *src; /* current position */ - const char *p; /* pattern */ - const char *lastmatch; /* end of last match */ - MatchState ms; /* match state */ -} GMatchState; - - -static int gmatch_aux (lua_State *L) { - GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3)); - const char *src; - gm->ms.L = L; - for (src = gm->src; src <= gm->ms.src_end; src++) { - const char *e; - reprepstate(&gm->ms); - if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) { - gm->src = gm->lastmatch = e; - return push_captures(&gm->ms, src, e); - } - } - return 0; /* not found */ -} - - -static int gmatch (lua_State *L) { - size_t ls, lp; - const char *s = luaL_checklstring(L, 1, &ls); - const char *p = luaL_checklstring(L, 2, &lp); - size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1; - GMatchState *gm; - lua_settop(L, 2); /* keep strings on closure to avoid being collected */ - gm = (GMatchState *)lua_newuserdatauv(L, sizeof(GMatchState), 0); - if (init > ls) /* start after string's end? */ - init = ls + 1; /* avoid overflows in 's + init' */ - prepstate(&gm->ms, L, s, ls, p, lp); - gm->src = s + init; gm->p = p; gm->lastmatch = NULL; - lua_pushcclosure(L, gmatch_aux, 3); - return 1; -} - - -static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e) { - size_t l; - lua_State *L = ms->L; - const char *news = lua_tolstring(L, 3, &l); - const char *p; - while ((p = (char *)memchr(news, L_ESC, l)) != NULL) { - luaL_addlstring(b, news, p - news); - p++; /* skip ESC */ - if (*p == L_ESC) /* '%%' */ - luaL_addchar(b, *p); - else if (*p == '0') /* '%0' */ - luaL_addlstring(b, s, e - s); - else if (isdigit(uchar(*p))) { /* '%n' */ - const char *cap; - ptrdiff_t resl = get_onecapture(ms, *p - '1', s, e, &cap); - if (resl == CAP_POSITION) - luaL_addvalue(b); /* add position to accumulated result */ - else - luaL_addlstring(b, cap, resl); - } - else - luaL_error(L, "invalid use of '%c' in replacement string", L_ESC); - l -= p + 1 - news; - news = p + 1; - } - luaL_addlstring(b, news, l); -} - - -/* -** Add the replacement value to the string buffer 'b'. -** Return true if the original string was changed. (Function calls and -** table indexing resulting in nil or false do not change the subject.) -*/ -static int add_value (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e, int tr) { - lua_State *L = ms->L; - switch (tr) { - case LUA_TFUNCTION: { /* call the function */ - int n; - lua_pushvalue(L, 3); /* push the function */ - n = push_captures(ms, s, e); /* all captures as arguments */ - lua_call(L, n, 1); /* call it */ - break; - } - case LUA_TTABLE: { /* index the table */ - push_onecapture(ms, 0, s, e); /* first capture is the index */ - lua_gettable(L, 3); - break; - } - default: { /* LUA_TNUMBER or LUA_TSTRING */ - add_s(ms, b, s, e); /* add value to the buffer */ - return 1; /* something changed */ - } - } - if (!lua_toboolean(L, -1)) { /* nil or false? */ - lua_pop(L, 1); /* remove value */ - luaL_addlstring(b, s, e - s); /* keep original text */ - return 0; /* no changes */ - } - else if (l_unlikely(!lua_isstring(L, -1))) - return luaL_error(L, "invalid replacement value (a %s)", - luaL_typename(L, -1)); - else { - luaL_addvalue(b); /* add result to accumulator */ - return 1; /* something changed */ - } -} - - -static int str_gsub (lua_State *L) { - size_t srcl, lp; - const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ - const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ - const char *lastmatch = NULL; /* end of last match */ - int tr = lua_type(L, 3); /* replacement type */ - lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ - int anchor = (*p == '^'); - lua_Integer n = 0; /* replacement count */ - int changed = 0; /* change flag */ - MatchState ms; - luaL_Buffer b; - luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || - tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, - "string/function/table"); - luaL_buffinit(L, &b); - if (anchor) { - p++; lp--; /* skip anchor character */ - } - prepstate(&ms, L, src, srcl, p, lp); - while (n < max_s) { - const char *e; - reprepstate(&ms); /* (re)prepare state for new match */ - if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ - n++; - changed = add_value(&ms, &b, src, e, tr) | changed; - src = lastmatch = e; - } - else if (src < ms.src_end) /* otherwise, skip one character */ - luaL_addchar(&b, *src++); - else break; /* end of subject */ - if (anchor) break; - } - if (!changed) /* no changes? */ - lua_pushvalue(L, 1); /* return original string */ - else { /* something changed */ - luaL_addlstring(&b, src, ms.src_end-src); - luaL_pushresult(&b); /* create and return new string */ - } - lua_pushinteger(L, n); /* number of substitutions */ - return 2; -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** STRING FORMAT -** ======================================================= -*/ - -#if !defined(lua_number2strx) /* { */ - -/* -** Hexadecimal floating-point formatter -*/ - -#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_floatatt(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, int sz, lua_Number x) { - /* if 'inf' or 'NaN', format it like '%g' */ - if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL) - return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x); - else if (x == 0) { /* can be -0... */ - /* create "0" or "-0" followed by exponent */ - return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x); - } - 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 sign */ - 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 += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */ - lua_assert(n < sz); - return n; - } -} - - -static int lua_number2strx (lua_State *L, char *buff, int sz, - const char *fmt, lua_Number x) { - int n = num2straux(buff, sz, x); - if (fmt[SIZELENMOD] == 'A') { - int i; - for (i = 0; i < n; i++) - buff[i] = toupper(uchar(buff[i])); - } - else if (l_unlikely(fmt[SIZELENMOD] != 'a')) - return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented"); - return n; -} - -#endif /* } */ - - -/* -** Maximum size for items formatted with '%f'. This size is produced -** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.', -** and '\0') + number of decimal digits to represent maxfloat (which -** is maximum exponent + 1). (99+3+1, adding some extra, 110) -*/ -#define MAX_ITEMF (110 + l_floatatt(MAX_10_EXP)) - - -/* -** All formats except '%f' do not need that large limit. The other -** float formats use exponents, so that they fit in the 99 limit for -** significant digits; 's' for large strings and 'q' add items directly -** to the buffer; all integer formats also fit in the 99 limit. The -** worst case are floats: they may need 99 significant digits, plus -** '0x', '-', '.', 'e+XXXX', and '\0'. Adding some extra, 120. -*/ -#define MAX_ITEM 120 - - -/* valid flags in a format specification */ -#if !defined(L_FMTFLAGS) -#define L_FMTFLAGS "-+ #0" -#endif - - -/* -** maximum size of each format specification (such as "%-099.99d") -*/ -#define MAX_FORMAT 32 - - -static void addquoted (luaL_Buffer *b, const char *s, size_t len) { - luaL_addchar(b, '"'); - while (len--) { - if (*s == '"' || *s == '\\' || *s == '\n') { - luaL_addchar(b, '\\'); - luaL_addchar(b, *s); - } - else if (iscntrl(uchar(*s))) { - char buff[10]; - if (!isdigit(uchar(*(s+1)))) - l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s)); - else - l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s)); - luaL_addstring(b, buff); - } - else - luaL_addchar(b, *s); - s++; - } - luaL_addchar(b, '"'); -} - - -/* -** Serialize a floating-point number in such a way that it can be -** scanned back by Lua. Use hexadecimal format for "common" numbers -** (to preserve precision); inf, -inf, and NaN are handled separately. -** (NaN cannot be expressed as a numeral, so we write '(0/0)' for it.) -*/ -static int quotefloat (lua_State *L, char *buff, lua_Number n) { - const char *s; /* for the fixed representations */ - if (n == (lua_Number)HUGE_VAL) /* inf? */ - s = "1e9999"; - else if (n == -(lua_Number)HUGE_VAL) /* -inf? */ - s = "-1e9999"; - else if (n != n) /* NaN? */ - s = "(0/0)"; - else { /* format number as hexadecimal */ - int nb = lua_number2strx(L, buff, MAX_ITEM, - "%" LUA_NUMBER_FRMLEN "a", n); - /* ensures that 'buff' string uses a dot as the radix character */ - if (memchr(buff, '.', nb) == NULL) { /* no dot? */ - char point = lua_getlocaledecpoint(); /* try locale point */ - char *ppoint = (char *)memchr(buff, point, nb); - if (ppoint) *ppoint = '.'; /* change it to a dot */ - } - return nb; - } - /* for the fixed representations */ - return l_sprintf(buff, MAX_ITEM, "%s", s); -} - - -static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { - switch (lua_type(L, arg)) { - case LUA_TSTRING: { - size_t len; - const char *s = lua_tolstring(L, arg, &len); - addquoted(b, s, len); - break; - } - case LUA_TNUMBER: { - char *buff = luaL_prepbuffsize(b, MAX_ITEM); - int nb; - if (!lua_isinteger(L, arg)) /* float? */ - nb = quotefloat(L, buff, lua_tonumber(L, arg)); - else { /* integers */ - lua_Integer n = lua_tointeger(L, arg); - const char *format = (n == LUA_MININTEGER) /* corner case? */ - ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hex */ - : LUA_INTEGER_FMT; /* else use default format */ - nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n); - } - luaL_addsize(b, nb); - break; - } - case LUA_TNIL: case LUA_TBOOLEAN: { - luaL_tolstring(L, arg, NULL); - luaL_addvalue(b); - break; - } - default: { - luaL_argerror(L, arg, "value has no literal form"); - } - } -} - - -static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { - const char *p = strfrmt; - while (*p != '\0' && strchr(L_FMTFLAGS, *p) != NULL) p++; /* skip flags */ - if ((size_t)(p - strfrmt) >= sizeof(L_FMTFLAGS)/sizeof(char)) - luaL_error(L, "invalid format (repeated flags)"); - if (isdigit(uchar(*p))) p++; /* skip width */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - if (*p == '.') { - p++; - if (isdigit(uchar(*p))) p++; /* skip precision */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - } - 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; - *form = '\0'; - return p; -} - - -/* -** add length modifier into formats -*/ -static void addlenmod (char *form, const char *lenmod) { - size_t l = strlen(form); - size_t lm = strlen(lenmod); - char spec = form[l - 1]; - strcpy(form + l - 1, lenmod); - form[l + lm - 1] = spec; - form[l + lm] = '\0'; -} - - -static int str_format (lua_State *L) { - int top = lua_gettop(L); - int arg = 1; - size_t sfl; - const char *strfrmt = luaL_checklstring(L, arg, &sfl); - const char *strfrmt_end = strfrmt+sfl; - luaL_Buffer b; - luaL_buffinit(L, &b); - while (strfrmt < strfrmt_end) { - if (*strfrmt != L_ESC) - luaL_addchar(&b, *strfrmt++); - else if (*++strfrmt == L_ESC) - luaL_addchar(&b, *strfrmt++); /* %% */ - else { /* format item */ - char form[MAX_FORMAT]; /* to store the format ('%...') */ - int maxitem = MAX_ITEM; - char *buff = luaL_prepbuffsize(&b, maxitem); /* to put formatted item */ - int nb = 0; /* number of bytes in added item */ - if (++arg > top) - return luaL_argerror(L, arg, "no value"); - strfrmt = scanformat(L, strfrmt, form); - switch (*strfrmt++) { - case 'c': { - nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); - break; - } - case 'd': case 'i': - case 'o': case 'u': case 'x': case 'X': { - lua_Integer n = luaL_checkinteger(L, arg); - addlenmod(form, LUA_INTEGER_FRMLEN); - nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); - break; - } - case 'a': case 'A': - addlenmod(form, LUA_NUMBER_FRMLEN); - nb = lua_number2strx(L, buff, maxitem, form, - luaL_checknumber(L, arg)); - break; - case 'f': - maxitem = MAX_ITEMF; /* extra space for '%f' */ - buff = luaL_prepbuffsize(&b, maxitem); - /* FALLTHROUGH */ - case 'e': case 'E': case 'g': case 'G': { - lua_Number n = luaL_checknumber(L, arg); - addlenmod(form, LUA_NUMBER_FRMLEN); - nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); - break; - } - case 'p': { - const void *p = lua_topointer(L, arg); - if (p == NULL) { /* avoid calling 'printf' with argument NULL */ - p = "(null)"; /* result */ - form[strlen(form) - 1] = 's'; /* format it as a string */ - } - nb = l_sprintf(buff, maxitem, form, p); - break; - } - case 'q': { - if (form[2] != '\0') /* modifiers? */ - return luaL_error(L, "specifier '%%q' cannot have modifiers"); - addliteral(L, &b, arg); - break; - } - case 's': { - size_t l; - const char *s = luaL_tolstring(L, arg, &l); - if (form[2] == '\0') /* no modifiers? */ - luaL_addvalue(&b); /* keep entire string */ - else { - luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); - if (!strchr(form, '.') && l >= 100) { - /* no precision and string is too long to be formatted */ - luaL_addvalue(&b); /* keep entire string */ - } - else { /* format the string into 'buff' */ - nb = l_sprintf(buff, maxitem, form, s); - lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ - } - } - break; - } - default: { /* also treat cases 'pnLlh' */ - return luaL_error(L, "invalid conversion '%s' to 'format'", form); - } - } - lua_assert(nb < maxitem); - luaL_addsize(&b, nb); - } - } - luaL_pushresult(&b); - return 1; -} - -/* }====================================================== */ - - -/* -** {====================================================== -** PACK/UNPACK -** ======================================================= -*/ - - -/* value used for padding */ -#if !defined(LUAL_PACKPADBYTE) -#define LUAL_PACKPADBYTE 0x00 -#endif - -/* maximum size for the binary representation of an integer */ -#define MAXINTSIZE 16 - -/* number of bits in a character */ -#define NB CHAR_BIT - -/* mask for one character (NB 1's) */ -#define MC ((1 << NB) - 1) - -/* size of a lua_Integer */ -#define SZINT ((int)sizeof(lua_Integer)) - - -/* dummy union to get native endianness */ -static const union { - int dummy; - char little; /* true iff machine is little endian */ -} nativeendian = {1}; - - -/* dummy structure to get native alignment requirements */ -struct cD { - char c; - union { double d; void *p; lua_Integer i; lua_Number n; } u; -}; - -#define MAXALIGN (offsetof(struct cD, u)) - - -/* -** information to pack/unpack stuff -*/ -typedef struct Header { - lua_State *L; - int islittle; - int maxalign; -} Header; - - -/* -** options for pack/unpack -*/ -typedef enum KOption { - Kint, /* signed integers */ - Kuint, /* unsigned integers */ - Kfloat, /* single-precision floating-point numbers */ - Knumber, /* Lua "native" floating-point numbers */ - Kdouble, /* double-precision floating-point numbers */ - Kchar, /* fixed-length strings */ - Kstring, /* strings with prefixed length */ - Kzstr, /* zero-terminated strings */ - Kpadding, /* padding */ - Kpaddalign, /* padding for alignment */ - Knop /* no-op (configuration or spaces) */ -} KOption; - - -/* -** Read an integer numeral from string 'fmt' or return 'df' if -** there is no numeral -*/ -static int digit (int c) { return '0' <= c && c <= '9'; } - -static int getnum (const char **fmt, int df) { - if (!digit(**fmt)) /* no number? */ - return df; /* return default value */ - else { - int a = 0; - do { - a = a*10 + (*((*fmt)++) - '0'); - } while (digit(**fmt) && a <= ((int)MAXSIZE - 9)/10); - return a; - } -} - - -/* -** Read an integer numeral and raises an error if it is larger -** than the maximum size for integers. -*/ -static int getnumlimit (Header *h, const char **fmt, int df) { - int sz = getnum(fmt, df); - if (l_unlikely(sz > MAXINTSIZE || sz <= 0)) - return luaL_error(h->L, "integral size (%d) out of limits [1,%d]", - sz, MAXINTSIZE); - return sz; -} - - -/* -** Initialize Header -*/ -static void initheader (lua_State *L, Header *h) { - h->L = L; - h->islittle = nativeendian.little; - h->maxalign = 1; -} - - -/* -** Read and classify next option. 'size' is filled with option's size. -*/ -static KOption getoption (Header *h, const char **fmt, int *size) { - int opt = *((*fmt)++); - *size = 0; /* default */ - switch (opt) { - case 'b': *size = sizeof(char); return Kint; - case 'B': *size = sizeof(char); return Kuint; - case 'h': *size = sizeof(short); return Kint; - case 'H': *size = sizeof(short); return Kuint; - case 'l': *size = sizeof(long); return Kint; - case 'L': *size = sizeof(long); return Kuint; - case 'j': *size = sizeof(lua_Integer); return Kint; - case 'J': *size = sizeof(lua_Integer); return Kuint; - case 'T': *size = sizeof(size_t); return Kuint; - case 'f': *size = sizeof(float); return Kfloat; - case 'n': *size = sizeof(lua_Number); return Knumber; - case 'd': *size = sizeof(double); return Kdouble; - case 'i': *size = getnumlimit(h, fmt, sizeof(int)); return Kint; - case 'I': *size = getnumlimit(h, fmt, sizeof(int)); return Kuint; - case 's': *size = getnumlimit(h, fmt, sizeof(size_t)); return Kstring; - case 'c': - *size = getnum(fmt, -1); - if (l_unlikely(*size == -1)) - luaL_error(h->L, "missing size for format option 'c'"); - return Kchar; - case 'z': return Kzstr; - case 'x': *size = 1; return Kpadding; - case 'X': return Kpaddalign; - case ' ': break; - case '<': h->islittle = 1; break; - case '>': h->islittle = 0; break; - case '=': h->islittle = nativeendian.little; break; - case '!': h->maxalign = getnumlimit(h, fmt, MAXALIGN); break; - default: luaL_error(h->L, "invalid format option '%c'", opt); - } - return Knop; -} - - -/* -** Read, classify, and fill other details about the next option. -** 'psize' is filled with option's size, 'notoalign' with its -** alignment requirements. -** Local variable 'size' gets the size to be aligned. (Kpadal option -** always gets its full alignment, other options are limited by -** the maximum alignment ('maxalign'). Kchar option needs no alignment -** despite its size. -*/ -static KOption getdetails (Header *h, size_t totalsize, - const char **fmt, int *psize, int *ntoalign) { - KOption opt = getoption(h, fmt, psize); - int align = *psize; /* usually, alignment follows size */ - if (opt == Kpaddalign) { /* 'X' gets alignment from following option */ - if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0) - luaL_argerror(h->L, 1, "invalid next option for option 'X'"); - } - if (align <= 1 || opt == Kchar) /* need no alignment? */ - *ntoalign = 0; - else { - if (align > h->maxalign) /* enforce maximum alignment */ - align = h->maxalign; - if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */ - luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); - *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1); - } - return opt; -} - - -/* -** Pack integer 'n' with 'size' bytes and 'islittle' endianness. -** The final 'if' handles the case when 'size' is larger than -** the size of a Lua integer, correcting the extra sign-extension -** bytes if necessary (by default they would be zeros). -*/ -static void packint (luaL_Buffer *b, lua_Unsigned n, - int islittle, int size, int neg) { - char *buff = luaL_prepbuffsize(b, size); - int i; - buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */ - for (i = 1; i < size; i++) { - n >>= NB; - buff[islittle ? i : size - 1 - i] = (char)(n & MC); - } - if (neg && size > SZINT) { /* negative number need sign extension? */ - for (i = SZINT; i < size; i++) /* correct extra bytes */ - buff[islittle ? i : size - 1 - i] = (char)MC; - } - luaL_addsize(b, size); /* add result to buffer */ -} - - -/* -** Copy 'size' bytes from 'src' to 'dest', correcting endianness if -** given 'islittle' is different from native endianness. -*/ -static void copywithendian (char *dest, const char *src, - int size, int islittle) { - if (islittle == nativeendian.little) - memcpy(dest, src, size); - else { - dest += size - 1; - while (size-- != 0) - *(dest--) = *(src++); - } -} - - -static int str_pack (lua_State *L) { - luaL_Buffer b; - Header h; - const char *fmt = luaL_checkstring(L, 1); /* format string */ - int arg = 1; /* current argument to pack */ - size_t totalsize = 0; /* accumulate total size of result */ - initheader(L, &h); - lua_pushnil(L); /* mark to separate arguments from string buffer */ - luaL_buffinit(L, &b); - while (*fmt != '\0') { - int size, ntoalign; - KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); - totalsize += ntoalign + size; - while (ntoalign-- > 0) - luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ - arg++; - switch (opt) { - case Kint: { /* signed integers */ - lua_Integer n = luaL_checkinteger(L, arg); - if (size < SZINT) { /* need overflow check? */ - lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); - luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); - } - packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); - break; - } - case Kuint: { /* unsigned integers */ - lua_Integer n = luaL_checkinteger(L, arg); - if (size < SZINT) /* need overflow check? */ - luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), - arg, "unsigned overflow"); - packint(&b, (lua_Unsigned)n, h.islittle, size, 0); - break; - } - case Kfloat: { /* C float */ - float f = (float)luaL_checknumber(L, arg); /* get argument */ - char *buff = luaL_prepbuffsize(&b, sizeof(f)); - /* move 'f' to final result, correcting endianness if needed */ - copywithendian(buff, (char *)&f, sizeof(f), h.islittle); - luaL_addsize(&b, size); - break; - } - case Knumber: { /* Lua float */ - lua_Number f = luaL_checknumber(L, arg); /* get argument */ - char *buff = luaL_prepbuffsize(&b, sizeof(f)); - /* move 'f' to final result, correcting endianness if needed */ - copywithendian(buff, (char *)&f, sizeof(f), h.islittle); - luaL_addsize(&b, size); - break; - } - case Kdouble: { /* C double */ - double f = (double)luaL_checknumber(L, arg); /* get argument */ - char *buff = luaL_prepbuffsize(&b, sizeof(f)); - /* move 'f' to final result, correcting endianness if needed */ - copywithendian(buff, (char *)&f, sizeof(f), h.islittle); - luaL_addsize(&b, size); - break; - } - case Kchar: { /* fixed-size string */ - size_t len; - const char *s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, len <= (size_t)size, arg, - "string longer than given size"); - luaL_addlstring(&b, s, len); /* add string */ - while (len++ < (size_t)size) /* pad extra space */ - luaL_addchar(&b, LUAL_PACKPADBYTE); - break; - } - case Kstring: { /* strings with length count */ - size_t len; - const char *s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, size >= (int)sizeof(size_t) || - len < ((size_t)1 << (size * NB)), - arg, "string length does not fit in given size"); - packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ - luaL_addlstring(&b, s, len); - totalsize += len; - break; - } - case Kzstr: { /* zero-terminated string */ - size_t len; - const char *s = luaL_checklstring(L, arg, &len); - luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); - luaL_addlstring(&b, s, len); - luaL_addchar(&b, '\0'); /* add zero at the end */ - totalsize += len + 1; - break; - } - case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ - case Kpaddalign: case Knop: - arg--; /* undo increment */ - break; - } - } - luaL_pushresult(&b); - return 1; -} - - -static int str_packsize (lua_State *L) { - Header h; - const char *fmt = luaL_checkstring(L, 1); /* format string */ - size_t totalsize = 0; /* accumulate total size of result */ - initheader(L, &h); - while (*fmt != '\0') { - int size, ntoalign; - KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); - luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, - "variable-length format"); - size += ntoalign; /* total space used by option */ - luaL_argcheck(L, totalsize <= MAXSIZE - size, 1, - "format result too large"); - totalsize += size; - } - lua_pushinteger(L, (lua_Integer)totalsize); - return 1; -} - - -/* -** Unpack an integer with 'size' bytes and 'islittle' endianness. -** If size is smaller than the size of a Lua integer and integer -** is signed, must do sign extension (propagating the sign to the -** higher bits); if size is larger than the size of a Lua integer, -** it must check the unread bytes to see whether they do not cause an -** overflow. -*/ -static lua_Integer unpackint (lua_State *L, const char *str, - int islittle, int size, int issigned) { - lua_Unsigned res = 0; - int i; - int limit = (size <= SZINT) ? size : SZINT; - for (i = limit - 1; i >= 0; i--) { - res <<= NB; - res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i]; - } - if (size < SZINT) { /* real size smaller than lua_Integer? */ - if (issigned) { /* needs sign extension? */ - lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1); - res = ((res ^ mask) - mask); /* do sign extension */ - } - } - else if (size > SZINT) { /* must check unread bytes */ - int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC; - for (i = limit; i < size; i++) { - if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask)) - luaL_error(L, "%d-byte integer does not fit into Lua Integer", size); - } - } - return (lua_Integer)res; -} - - -static int str_unpack (lua_State *L) { - Header h; - const char *fmt = luaL_checkstring(L, 1); - size_t ld; - const char *data = luaL_checklstring(L, 2, &ld); - size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1; - int n = 0; /* number of results */ - luaL_argcheck(L, pos <= ld, 3, "initial position out of string"); - initheader(L, &h); - while (*fmt != '\0') { - int size, ntoalign; - KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign); - luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2, - "data string too short"); - pos += ntoalign; /* skip alignment */ - /* stack space for item + next position */ - luaL_checkstack(L, 2, "too many results"); - n++; - switch (opt) { - case Kint: - case Kuint: { - lua_Integer res = unpackint(L, data + pos, h.islittle, size, - (opt == Kint)); - lua_pushinteger(L, res); - break; - } - case Kfloat: { - float f; - copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); - lua_pushnumber(L, (lua_Number)f); - break; - } - case Knumber: { - lua_Number f; - copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); - lua_pushnumber(L, f); - break; - } - case Kdouble: { - double f; - copywithendian((char *)&f, data + pos, sizeof(f), h.islittle); - lua_pushnumber(L, (lua_Number)f); - break; - } - case Kchar: { - lua_pushlstring(L, data + pos, size); - break; - } - case Kstring: { - size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0); - luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short"); - lua_pushlstring(L, data + pos + size, len); - pos += len; /* skip string */ - break; - } - case Kzstr: { - size_t len = strlen(data + pos); - luaL_argcheck(L, pos + len < ld, 2, - "unfinished string for format 'z'"); - lua_pushlstring(L, data + pos, len); - pos += len + 1; /* skip string plus final '\0' */ - break; - } - case Kpaddalign: case Kpadding: case Knop: - n--; /* undo increment */ - break; - } - pos += size; - } - lua_pushinteger(L, pos + 1); /* next position */ - return n + 1; -} - -/* }====================================================== */ - - -static const luaL_Reg strlib[] = { - {"byte", str_byte}, - {"char", str_char}, - {"dump", str_dump}, - {"find", str_find}, - {"format", str_format}, - {"gmatch", gmatch}, - {"gsub", str_gsub}, - {"len", str_len}, - {"lower", str_lower}, - {"match", str_match}, - {"rep", str_rep}, - {"reverse", str_reverse}, - {"sub", str_sub}, - {"upper", str_upper}, - {"pack", str_pack}, - {"packsize", str_packsize}, - {"unpack", str_unpack}, - {NULL, NULL} -}; - - -static void createmetatable (lua_State *L) { - /* table to be metatable for strings */ - luaL_newlibtable(L, stringmetamethods); - luaL_setfuncs(L, stringmetamethods, 0); - lua_pushliteral(L, ""); /* dummy string */ - lua_pushvalue(L, -2); /* copy table */ - lua_setmetatable(L, -2); /* set table as metatable for strings */ - lua_pop(L, 1); /* pop dummy string */ - lua_pushvalue(L, -2); /* get string library */ - lua_setfield(L, -2, "__index"); /* metatable.__index = string */ - lua_pop(L, 1); /* pop metatable */ -} - - -/* -** Open string library -*/ -LUAMOD_API int luaopen_string (lua_State *L) { - luaL_newlib(L, strlib); - createmetatable(L); - return 1; -} - diff --git a/source/external/lua/ltable.c b/source/external/lua/ltable.c deleted file mode 100644 index 33c1ab3..0000000 --- a/source/external/lua/ltable.c +++ /dev/null @@ -1,971 +0,0 @@ -/* -** $Id: ltable.c $ -** Lua tables (hash) -** See Copyright Notice in lua.h -*/ - -#define ltable_c -#define LUA_CORE - -#include "lprefix.h" - - -/* -** 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 -** 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 -** to it), then the colliding element is in its own main position. -** Hence even when the load factor reaches 100%, performance remains good. -*/ - -#include -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lgc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "lvm.h" - - -/* -** MAXABITS is the largest integer such that MAXASIZE fits in an -** unsigned int. -*/ -#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1) - - -/* -** MAXASIZE is the maximum size of the array part. It is the minimum -** between 2^MAXABITS and the maximum size that, measured in bytes, -** fits in a 'size_t'. -*/ -#define MAXASIZE luaM_limitN(1u << MAXABITS, TValue) - -/* -** MAXHBITS is the largest integer such that 2^MAXHBITS fits in a -** signed int. -*/ -#define MAXHBITS (MAXABITS - 1) - - -/* -** MAXHSIZE is the maximum size of the hash part. It is the minimum -** between 2^MAXHBITS and the maximum size such that, measured in bytes, -** it fits in a 'size_t'. -*/ -#define MAXHSIZE luaM_limitN(1u << MAXHBITS, Node) - - -/* -** When the original hash value is good, hashing by a power of 2 -** avoids the cost of '%'. -*/ -#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) - -/* -** for other types, it is better to avoid modulo by power of 2, as -** they can have many 2 factors. -*/ -#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) - - -#define hashstr(t,str) hashpow2(t, (str)->hash) -#define hashboolean(t,p) hashpow2(t, p) - -#define hashint(t,i) hashpow2(t, i) - - -#define hashpointer(t,p) hashmod(t, point2uint(p)) - - -#define dummynode (&dummynode_) - -static const Node dummynode_ = { - {{NULL}, LUA_VEMPTY, /* value's value and type */ - LUA_VNIL, 0, {NULL}} /* key type, next, and key value */ -}; - - -static const TValue absentkey = {ABSTKEYCONSTANT}; - - - -/* -** Hash for floating-point numbers. -** The main computation should be just -** n = frexp(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. -*/ -#if !defined(l_hashfloat) -static int l_hashfloat (lua_Number n) { - int i; - 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) == cast_num(HUGE_VAL)); - return 0; - } - else { /* normal case */ - unsigned int u = cast_uint(i) + cast_uint(ni); - return cast_int(u <= cast_uint(INT_MAX) ? u : ~u); - } -} -#endif - - -/* -** returns the 'main' position of an element in a table (that is, -** the index of its hash value). The key comes broken (tag in 'ktt' -** and value in 'vkl') so that we can call it on keys inserted into -** nodes. -*/ -static Node *mainposition (const Table *t, int ktt, const Value *kvl) { - switch (withvariant(ktt)) { - case LUA_VNUMINT: { - lua_Integer key = ivalueraw(*kvl); - return hashint(t, key); - } - case LUA_VNUMFLT: { - lua_Number n = fltvalueraw(*kvl); - return hashmod(t, l_hashfloat(n)); - } - case LUA_VSHRSTR: { - TString *ts = tsvalueraw(*kvl); - return hashstr(t, ts); - } - case LUA_VLNGSTR: { - TString *ts = tsvalueraw(*kvl); - return hashpow2(t, luaS_hashlongstr(ts)); - } - case LUA_VFALSE: - return hashboolean(t, 0); - case LUA_VTRUE: - return hashboolean(t, 1); - case LUA_VLIGHTUSERDATA: { - void *p = pvalueraw(*kvl); - return hashpointer(t, p); - } - case LUA_VLCF: { - lua_CFunction f = fvalueraw(*kvl); - return hashpointer(t, f); - } - default: { - GCObject *o = gcvalueraw(*kvl); - return hashpointer(t, o); - } - } -} - - -/* -** Returns the main position of an element given as a 'TValue' -*/ -static Node *mainpositionTV (const Table *t, const TValue *key) { - return mainposition(t, rawtt(key), valraw(key)); -} - - -/* -** Check whether key 'k1' is equal to the key in node 'n2'. This -** equality is raw, so there are no metamethods. Floats with integer -** values have been normalized, so integers cannot be equal to -** floats. It is assumed that 'eqshrstr' is simply pointer equality, so -** that short strings are handled in the default case. -** A true 'deadok' means to accept dead keys as equal to their original -** values. All dead keys are compared in the default case, by pointer -** identity. (Only collectable objects can produce dead keys.) Note that -** dead long strings are also compared by identity. -** Once a key is dead, its corresponding value may be collected, and -** then another value can be created with the same address. If this -** other value is given to 'next', 'equalkey' will signal a false -** positive. In a regular traversal, this situation should never happen, -** as all keys given to 'next' came from the table itself, and therefore -** could not have been collected. Outside a regular traversal, we -** have garbage in, garbage out. What is relevant is that this false -** positive does not break anything. (In particular, 'next' will return -** some other valid item on the table or nil.) -*/ -static int equalkey (const TValue *k1, const Node *n2, int deadok) { - if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ - !(deadok && keyisdead(n2) && iscollectable(k1))) - return 0; /* cannot be same key */ - switch (keytt(n2)) { - case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: - return 1; - case LUA_VNUMINT: - return (ivalue(k1) == keyival(n2)); - case LUA_VNUMFLT: - return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2))); - case LUA_VLIGHTUSERDATA: - return pvalue(k1) == pvalueraw(keyval(n2)); - case LUA_VLCF: - return fvalue(k1) == fvalueraw(keyval(n2)); - case ctb(LUA_VLNGSTR): - return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); - default: - return gcvalue(k1) == gcvalueraw(keyval(n2)); - } -} - - -/* -** True if value of 'alimit' is equal to the real size of the array -** part of table 't'. (Otherwise, the array part must be larger than -** 'alimit'.) -*/ -#define limitequalsasize(t) (isrealasize(t) || ispow2((t)->alimit)) - - -/* -** Returns the real size of the 'array' array -*/ -LUAI_FUNC unsigned int luaH_realasize (const Table *t) { - if (limitequalsasize(t)) - return t->alimit; /* this is the size */ - else { - unsigned int size = t->alimit; - /* compute the smallest power of 2 not smaller than 'n' */ - size |= (size >> 1); - size |= (size >> 2); - size |= (size >> 4); - size |= (size >> 8); - size |= (size >> 16); -#if (UINT_MAX >> 30) > 3 - size |= (size >> 32); /* unsigned int has more than 32 bits */ -#endif - size++; - lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size); - return size; - } -} - - -/* -** Check whether real size of the array is a power of 2. -** (If it is not, 'alimit' cannot be changed to any other value -** without changing the real size.) -*/ -static int ispow2realasize (const Table *t) { - return (!isrealasize(t) || ispow2(t->alimit)); -} - - -static unsigned int setlimittosize (Table *t) { - t->alimit = luaH_realasize(t); - setrealasize(t); - return t->alimit; -} - - -#define limitasasize(t) check_exp(isrealasize(t), t->alimit) - - - -/* -** "Generic" get version. (Not that generic: not valid for integers, -** which may be in array part, nor for floats with integral values.) -** See explanation about 'deadok' in function 'equalkey'. -*/ -static const TValue *getgeneric (Table *t, const TValue *key, int deadok) { - Node *n = mainpositionTV(t, key); - for (;;) { /* check whether 'key' is somewhere in the chain */ - if (equalkey(key, n, deadok)) - return gval(n); /* that's it */ - else { - int nx = gnext(n); - if (nx == 0) - return &absentkey; /* not found */ - n += nx; - } - } -} - - -/* -** returns the index for 'k' if 'k' is an appropriate key to live in -** the array part of a table, 0 otherwise. -*/ -static unsigned int arrayindex (lua_Integer k) { - if (l_castS2U(k) - 1u < MAXASIZE) /* 'k' in [1, MAXASIZE]? */ - return cast_uint(k); /* 'key' is an appropriate array index */ - else - return 0; -} - - -/* -** returns the index of a 'key' for table traversals. First goes all -** elements in the array part, then elements in the hash part. The -** beginning of a traversal is signaled by 0. -*/ -static unsigned int findindex (lua_State *L, Table *t, TValue *key, - unsigned int asize) { - unsigned int i; - if (ttisnil(key)) return 0; /* first iteration */ - i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0; - if (i - 1u < asize) /* is 'key' inside array part? */ - return i; /* yes; that's the index */ - else { - const TValue *n = getgeneric(t, key, 1); - if (l_unlikely(isabstkey(n))) - luaG_runerror(L, "invalid key to 'next'"); /* key not found */ - i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ - /* hash elements are numbered after array ones */ - return (i + 1) + asize; - } -} - - -int luaH_next (lua_State *L, Table *t, StkId key) { - unsigned int asize = luaH_realasize(t); - unsigned int i = findindex(L, t, s2v(key), asize); /* find original key */ - for (; i < asize; i++) { /* try first array part */ - if (!isempty(&t->array[i])) { /* a non-empty entry? */ - setivalue(s2v(key), i + 1); - setobj2s(L, key + 1, &t->array[i]); - return 1; - } - } - for (i -= asize; cast_int(i) < sizenode(t); i++) { /* hash part */ - if (!isempty(gval(gnode(t, i)))) { /* a non-empty entry? */ - Node *n = gnode(t, i); - getnodekey(L, s2v(key), n); - setobj2s(L, key + 1, gval(n)); - return 1; - } - } - return 0; /* no more elements */ -} - - -static void freehash (lua_State *L, Table *t) { - if (!isdummy(t)) - luaM_freearray(L, t->node, cast_sizet(sizenode(t))); -} - - -/* -** {============================================================= -** Rehash -** ============================================================== -*/ - -/* -** 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. '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. (The condition -** 'twotoi > 0' in the for loop stops the loop if 'twotoi' overflows.) -*/ -static unsigned int computesizes (unsigned int nums[], unsigned int *pna) { - int 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 optimal = 0; /* optimal size for array part */ - /* loop while keys can fill more than half of total size */ - for (i = 0, twotoi = 1; - twotoi > 0 && *pna > twotoi / 2; - i++, twotoi *= 2) { - a += nums[i]; - if (a > twotoi/2) { /* more than half elements present? */ - optimal = twotoi; /* optimal size (till now) */ - na = a; /* all elements up to 'optimal' will go to array part */ - } - } - lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal); - *pna = na; - return optimal; -} - - -static int countint (lua_Integer key, unsigned int *nums) { - unsigned int k = arrayindex(key); - if (k != 0) { /* is 'key' an appropriate array index? */ - nums[luaO_ceillog2(k)]++; /* count as such */ - return 1; - } - else - return 0; -} - - -/* -** 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 */ - unsigned int ause = 0; /* summation of 'nums' */ - unsigned int i = 1; /* count to traverse all array keys */ - unsigned int asize = limitasasize(t); /* real array size */ - /* traverse each slice */ - for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2) { - unsigned int lc = 0; /* counter */ - unsigned int lim = ttlg; - if (lim > asize) { - lim = asize; /* adjust upper limit */ - if (i > lim) - break; /* no more elements to count */ - } - /* count elements in range (2^(lg - 1), 2^lg] */ - for (; i <= lim; i++) { - if (!isempty(&t->array[i-1])) - lc++; - } - nums[lg] += lc; - ause += lc; - } - return ause; -} - - -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); - while (i--) { - Node *n = &t->node[i]; - if (!isempty(gval(n))) { - if (keyisinteger(n)) - ause += countint(keyival(n), nums); - totaluse++; - } - } - *pna += ause; - return totaluse; -} - - -/* -** Creates an array for the hash part of a table with the given -** size, or reuses the dummy node if size is zero. -** The computation for size overflow is in two steps: the first -** comparison ensures that the shift in the second one does not -** overflow. -*/ -static void setnodevector (lua_State *L, Table *t, unsigned int size) { - if (size == 0) { /* no elements to hash part? */ - t->node = cast(Node *, dummynode); /* use common 'dummynode' */ - t->lsizenode = 0; - t->lastfree = NULL; /* signal that it is using dummy node */ - } - else { - int i; - int lsize = luaO_ceillog2(size); - if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE) - luaG_runerror(L, "table overflow"); - size = twoto(lsize); - t->node = luaM_newvector(L, size, Node); - for (i = 0; i < (int)size; i++) { - Node *n = gnode(t, i); - gnext(n) = 0; - setnilkey(n); - setempty(gval(n)); - } - t->lsizenode = cast_byte(lsize); - t->lastfree = gnode(t, size); /* all positions are free */ - } -} - - -/* -** (Re)insert all elements from the hash part of 'ot' into table 't'. -*/ -static void reinsert (lua_State *L, Table *ot, Table *t) { - int j; - int size = sizenode(ot); - for (j = 0; j < size; j++) { - Node *old = gnode(ot, j); - if (!isempty(gval(old))) { - /* doesn't need barrier/invalidate cache, as entry was - already present in the table */ - TValue k; - getnodekey(L, &k, old); - luaH_set(L, t, &k, gval(old)); - } - } -} - - -/* -** Exchange the hash part of 't1' and 't2'. -*/ -static void exchangehashpart (Table *t1, Table *t2) { - lu_byte lsizenode = t1->lsizenode; - Node *node = t1->node; - Node *lastfree = t1->lastfree; - t1->lsizenode = t2->lsizenode; - t1->node = t2->node; - t1->lastfree = t2->lastfree; - t2->lsizenode = lsizenode; - t2->node = node; - t2->lastfree = lastfree; -} - - -/* -** Resize table 't' for the new given sizes. Both allocations (for -** the hash part and for the array part) can fail, which creates some -** subtleties. If the first allocation, for the hash part, fails, an -** error is raised and that is it. Otherwise, it copies the elements from -** the shrinking part of the array (if it is shrinking) into the new -** hash. Then it reallocates the array part. If that fails, the table -** is in its original state; the function frees the new hash part and then -** raises the allocation error. Otherwise, it sets the new hash part -** into the table, initializes the new part of the array (if any) with -** nils and reinserts the elements of the old hash back into the new -** parts of the table. -*/ -void luaH_resize (lua_State *L, Table *t, unsigned int newasize, - unsigned int nhsize) { - unsigned int i; - Table newt; /* to keep the new hash part */ - unsigned int oldasize = setlimittosize(t); - TValue *newarray; - /* create new hash part with appropriate size into 'newt' */ - setnodevector(L, &newt, nhsize); - if (newasize < oldasize) { /* will array shrink? */ - t->alimit = newasize; /* pretend array has new size... */ - exchangehashpart(t, &newt); /* and new hash */ - /* re-insert into the new hash the elements from vanishing slice */ - for (i = newasize; i < oldasize; i++) { - if (!isempty(&t->array[i])) - luaH_setint(L, t, i + 1, &t->array[i]); - } - t->alimit = oldasize; /* restore current size... */ - exchangehashpart(t, &newt); /* and hash (in case of errors) */ - } - /* allocate new array */ - newarray = luaM_reallocvector(L, t->array, oldasize, newasize, TValue); - if (l_unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ - freehash(L, &newt); /* release new hash part */ - luaM_error(L); /* raise error (with array unchanged) */ - } - /* allocation ok; initialize new part of the array */ - exchangehashpart(t, &newt); /* 't' has the new hash ('newt' has the old) */ - t->array = newarray; /* set new array part */ - t->alimit = newasize; - for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ - setempty(&t->array[i]); - /* re-insert elements from old hash part into new parts */ - reinsert(L, &newt, t); /* 'newt' now has the old hash */ - freehash(L, &newt); /* free old hash part */ -} - - -void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { - int nsize = allocsizenode(t); - luaH_resize(L, t, nasize, nsize); -} - -/* -** 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 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 */ - setlimittosize(t); - 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 */ - if (ttisinteger(ek)) - na += countint(ivalue(ek), nums); - totaluse++; - /* compute new size for array part */ - asize = computesizes(nums, &na); - /* resize the table to new computed sizes */ - luaH_resize(L, t, asize, totaluse - na); -} - - - -/* -** }============================================================= -*/ - - -Table *luaH_new (lua_State *L) { - GCObject *o = luaC_newobj(L, LUA_VTABLE, sizeof(Table)); - Table *t = gco2t(o); - t->metatable = NULL; - t->flags = cast_byte(maskflags); /* table has no metamethod fields */ - t->array = NULL; - t->alimit = 0; - setnodevector(L, t, 0); - return t; -} - - -void luaH_free (lua_State *L, Table *t) { - freehash(L, t); - luaM_freearray(L, t->array, luaH_realasize(t)); - luaM_free(L, t); -} - - -static Node *getfreepos (Table *t) { - if (!isdummy(t)) { - while (t->lastfree > t->node) { - t->lastfree--; - if (keyisnil(t->lastfree)) - return t->lastfree; - } - } - return NULL; /* could not find a free place */ -} - - - -/* -** inserts a new key into a hash table; first, check whether key's main -** position is free. If not, check whether colliding node is in its main -** position or not: if it is not, move colliding node to an empty place and -** put new key in its main position; otherwise (colliding node is in its main -** position), new key goes to an empty position. -*/ -void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { - Node *mp; - TValue aux; - if (l_unlikely(ttisnil(key))) - luaG_runerror(L, "table index is nil"); - else if (ttisfloat(key)) { - lua_Number f = fltvalue(key); - lua_Integer k; - if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */ - setivalue(&aux, k); - key = &aux; /* insert it as an integer */ - } - else if (l_unlikely(luai_numisnan(f))) - luaG_runerror(L, "table index is NaN"); - } - if (ttisnil(value)) - return; /* do not insert nil values */ - mp = mainpositionTV(t, key); - if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */ - Node *othern; - Node *f = getfreepos(t); /* get a free place */ - if (f == NULL) { /* cannot find a free place? */ - rehash(L, t, key); /* grow table */ - /* whatever called 'newkey' takes care of TM cache */ - luaH_set(L, t, key, value); /* insert key into grown table */ - return; - } - lua_assert(!isdummy(t)); - othern = mainposition(t, keytt(mp), &keyval(mp)); - if (othern != mp) { /* is colliding node out of its main position? */ - /* yes; move colliding node into free position */ - while (othern + gnext(othern) != mp) /* find previous */ - othern += gnext(othern); - gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */ - *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ - if (gnext(mp) != 0) { - gnext(f) += cast_int(mp - f); /* correct 'next' */ - gnext(mp) = 0; /* now 'mp' is free */ - } - setempty(gval(mp)); - } - else { /* colliding node is in its own main position */ - /* new node will go into free position */ - if (gnext(mp) != 0) - gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */ - else lua_assert(gnext(f) == 0); - gnext(mp) = cast_int(f - mp); - mp = f; - } - } - setnodekey(L, mp, key); - luaC_barrierback(L, obj2gco(t), key); - lua_assert(isempty(gval(mp))); - setobj2t(L, gval(mp), value); -} - - -/* -** Search function for integers. If integer is inside 'alimit', get it -** directly from the array part. Otherwise, if 'alimit' is not equal to -** the real size of the array, key still can be in the array part. In -** this case, try to avoid a call to 'luaH_realasize' when key is just -** one more than the limit (so that it can be incremented without -** changing the real size of the array). -*/ -const TValue *luaH_getint (Table *t, lua_Integer key) { - if (l_castS2U(key) - 1u < t->alimit) /* 'key' in [1, t->alimit]? */ - return &t->array[key - 1]; - else if (!limitequalsasize(t) && /* key still may be in the array part? */ - (l_castS2U(key) == t->alimit + 1 || - l_castS2U(key) - 1u < luaH_realasize(t))) { - t->alimit = cast_uint(key); /* probably '#t' is here now */ - return &t->array[key - 1]; - } - else { - Node *n = hashint(t, key); - for (;;) { /* check whether 'key' is somewhere in the chain */ - if (keyisinteger(n) && keyival(n) == key) - return gval(n); /* that's it */ - else { - int nx = gnext(n); - if (nx == 0) break; - n += nx; - } - } - return &absentkey; - } -} - - -/* -** search function for short strings -*/ -const TValue *luaH_getshortstr (Table *t, TString *key) { - Node *n = hashstr(t, key); - lua_assert(key->tt == LUA_VSHRSTR); - for (;;) { /* check whether 'key' is somewhere in the chain */ - if (keyisshrstr(n) && eqshrstr(keystrval(n), key)) - return gval(n); /* that's it */ - else { - int nx = gnext(n); - if (nx == 0) - return &absentkey; /* not found */ - n += nx; - } - } -} - - -const TValue *luaH_getstr (Table *t, TString *key) { - if (key->tt == LUA_VSHRSTR) - return luaH_getshortstr(t, key); - else { /* for long strings, use generic case */ - TValue ko; - setsvalue(cast(lua_State *, NULL), &ko, key); - return getgeneric(t, &ko, 0); - } -} - - -/* -** main search function -*/ -const TValue *luaH_get (Table *t, const TValue *key) { - switch (ttypetag(key)) { - case LUA_VSHRSTR: return luaH_getshortstr(t, tsvalue(key)); - case LUA_VNUMINT: return luaH_getint(t, ivalue(key)); - case LUA_VNIL: return &absentkey; - case LUA_VNUMFLT: { - lua_Integer k; - if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ - return luaH_getint(t, k); /* use specialized version */ - /* else... */ - } /* FALLTHROUGH */ - default: - return getgeneric(t, key, 0); - } -} - - -/* -** Finish a raw "set table" operation, where 'slot' is where the value -** should have been (the result of a previous "get table"). -** Beware: when using this function you probably need to check a GC -** barrier and invalidate the TM cache. -*/ -void luaH_finishset (lua_State *L, Table *t, const TValue *key, - const TValue *slot, TValue *value) { - if (isabstkey(slot)) - luaH_newkey(L, t, key, value); - else - setobj2t(L, cast(TValue *, slot), value); -} - - -/* -** beware: when using this function you probably need to check a GC -** barrier and invalidate the TM cache. -*/ -void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { - const TValue *slot = luaH_get(t, key); - luaH_finishset(L, t, key, slot, value); -} - - -void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { - const TValue *p = luaH_getint(t, key); - if (isabstkey(p)) { - TValue k; - setivalue(&k, key); - luaH_newkey(L, t, &k, value); - } - else - setobj2t(L, cast(TValue *, p), value); -} - - -/* -** Try to find a boundary in the hash part of table 't'. From the -** caller, we know that 'j' is zero or present and that 'j + 1' is -** present. We want to find a larger key that is absent from the -** table, so that we can do a binary search between the two keys to -** find a boundary. We keep doubling 'j' until we get an absent index. -** If the doubling would overflow, we try LUA_MAXINTEGER. If it is -** absent, we are ready for the binary search. ('j', being max integer, -** is larger or equal to 'i', but it cannot be equal because it is -** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a -** boundary. ('j + 1' cannot be a present integer key because it is -** not a valid integer in Lua.) -*/ -static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { - lua_Unsigned i; - if (j == 0) j++; /* the caller ensures 'j + 1' is present */ - do { - i = j; /* 'i' is a present index */ - if (j <= l_castS2U(LUA_MAXINTEGER) / 2) - j *= 2; - else { - j = LUA_MAXINTEGER; - if (isempty(luaH_getint(t, j))) /* t[j] not present? */ - break; /* 'j' now is an absent index */ - else /* weird case */ - return j; /* well, max integer is a boundary... */ - } - } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */ - /* i < j && t[i] present && t[j] absent */ - while (j - i > 1u) { /* do a binary search between them */ - lua_Unsigned m = (i + j) / 2; - if (isempty(luaH_getint(t, m))) j = m; - else i = m; - } - return i; -} - - -static unsigned int binsearch (const TValue *array, unsigned int i, - unsigned int j) { - while (j - i > 1u) { /* binary search */ - unsigned int m = (i + j) / 2; - if (isempty(&array[m - 1])) j = m; - else i = m; - } - return i; -} - - -/* -** Try to find a boundary in table 't'. (A 'boundary' is an integer index -** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent -** and 'maxinteger' if t[maxinteger] is present.) -** (In the next explanation, we use Lua indices, that is, with base 1. -** The code itself uses base 0 when indexing the array part of the table.) -** The code starts with 'limit = t->alimit', a position in the array -** part that may be a boundary. -** -** (1) If 't[limit]' is empty, there must be a boundary before it. -** As a common case (e.g., after 't[#t]=nil'), check whether 'limit-1' -** is present. If so, it is a boundary. Otherwise, do a binary search -** between 0 and limit to find a boundary. In both cases, try to -** use this boundary as the new 'alimit', as a hint for the next call. -** -** (2) If 't[limit]' is not empty and the array has more elements -** after 'limit', try to find a boundary there. Again, try first -** the special case (which should be quite frequent) where 'limit+1' -** is empty, so that 'limit' is a boundary. Otherwise, check the -** last element of the array part. If it is empty, there must be a -** boundary between the old limit (present) and the last element -** (absent), which is found with a binary search. (This boundary always -** can be a new limit.) -** -** (3) The last case is when there are no elements in the array part -** (limit == 0) or its last element (the new limit) is present. -** In this case, must check the hash part. If there is no hash part -** or 'limit+1' is absent, 'limit' is a boundary. Otherwise, call -** 'hash_search' to find a boundary in the hash part of the table. -** (In those cases, the boundary is not inside the array part, and -** therefore cannot be used as a new limit.) -*/ -lua_Unsigned luaH_getn (Table *t) { - unsigned int limit = t->alimit; - if (limit > 0 && isempty(&t->array[limit - 1])) { /* (1)? */ - /* there must be a boundary before 'limit' */ - if (limit >= 2 && !isempty(&t->array[limit - 2])) { - /* 'limit - 1' is a boundary; can it be a new limit? */ - if (ispow2realasize(t) && !ispow2(limit - 1)) { - t->alimit = limit - 1; - setnorealasize(t); /* now 'alimit' is not the real size */ - } - return limit - 1; - } - else { /* must search for a boundary in [0, limit] */ - unsigned int boundary = binsearch(t->array, 0, limit); - /* can this boundary represent the real size of the array? */ - if (ispow2realasize(t) && boundary > luaH_realasize(t) / 2) { - t->alimit = boundary; /* use it as the new limit */ - setnorealasize(t); - } - return boundary; - } - } - /* 'limit' is zero or present in table */ - if (!limitequalsasize(t)) { /* (2)? */ - /* 'limit' > 0 and array has more elements after 'limit' */ - if (isempty(&t->array[limit])) /* 'limit + 1' is empty? */ - return limit; /* this is the boundary */ - /* else, try last element in the array */ - limit = luaH_realasize(t); - if (isempty(&t->array[limit - 1])) { /* empty? */ - /* there must be a boundary in the array after old limit, - and it must be a valid new limit */ - unsigned int boundary = binsearch(t->array, t->alimit, limit); - t->alimit = boundary; - return boundary; - } - /* else, new limit is present in the table; check the hash part */ - } - /* (3) 'limit' is the last element and either is zero or present in table */ - lua_assert(limit == luaH_realasize(t) && - (limit == 0 || !isempty(&t->array[limit - 1]))); - if (isdummy(t) || isempty(luaH_getint(t, cast(lua_Integer, limit + 1)))) - return limit; /* 'limit + 1' is absent */ - else /* 'limit + 1' is also present */ - return hash_search(t, limit); -} - - - -#if defined(LUA_DEBUG) - -/* export these functions for the test library */ - -Node *luaH_mainposition (const Table *t, const TValue *key) { - return mainpositionTV(t, key); -} - -int luaH_isdummy (const Table *t) { return isdummy(t); } - -#endif diff --git a/source/external/lua/ltable.h b/source/external/lua/ltable.h index 7bbbcb2..f3b7bc7 100644 --- a/source/external/lua/ltable.h +++ b/source/external/lua/ltable.h @@ -20,11 +20,21 @@ ** may have any of these metamethods. (First access that fails after the ** clearing will set the bit again.) */ -#define invalidateTMcache(t) ((t)->flags &= ~maskflags) +#define invalidateTMcache(t) ((t)->flags &= cast_byte(~maskflags)) -/* true when 't' is using 'dummynode' as its hash part */ -#define isdummy(t) ((t)->lastfree == NULL) +/* +** Bit BITDUMMY set in 'flags' means the table is using the dummy node +** for its hash part. +*/ + +#define BITDUMMY (1 << 6) +#define NOTBITDUMMY cast_byte(~BITDUMMY) +#define isdummy(t) ((t)->flags & BITDUMMY) + +#define setnodummy(t) ((t)->flags &= NOTBITDUMMY) +#define setdummy(t) ((t)->flags |= BITDUMMY) + /* allocated size for hash nodes */ @@ -35,31 +45,139 @@ #define nodefromval(v) cast(Node *, (v)) -LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); + +#define luaH_fastgeti(t,k,res,tag) \ + { Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \ + if ((u < h->asize)) { \ + tag = *getArrTag(h, u); \ + if (!tagisempty(tag)) { farr2val(h, u, tag, res); }} \ + else { tag = luaH_getint(h, (k), res); }} + + +#define luaH_fastseti(t,k,val,hres) \ + { Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \ + if ((u < h->asize)) { \ + lu_byte *tag = getArrTag(h, u); \ + if (checknoTM(h->metatable, TM_NEWINDEX) || !tagisempty(*tag)) \ + { fval2arr(h, u, tag, val); hres = HOK; } \ + else hres = ~cast_int(u); } \ + else { hres = luaH_psetint(h, k, val); }} + + +/* results from pset */ +#define HOK 0 +#define HNOTFOUND 1 +#define HNOTATABLE 2 +#define HFIRSTNODE 3 + +/* +** 'luaH_get*' operations set 'res', unless the value is absent, and +** return the tag of the result. +** The 'luaH_pset*' (pre-set) operations set the given value and return +** HOK, unless the original value is absent. In that case, if the key +** is really absent, they return HNOTFOUND. Otherwise, if there is a +** slot with that key but with no value, 'luaH_pset*' return an encoding +** of where the key is (usually called 'hres'). (pset cannot set that +** value because there might be a metamethod.) If the slot is in the +** hash part, the encoding is (HFIRSTNODE + hash index); if the slot is +** in the array part, the encoding is (~array index), a negative value. +** The value HNOTATABLE is used by the fast macros to signal that the +** value being indexed is not a table. +** (The size for the array part is limited by the maximum power of two +** that fits in an unsigned integer; that is INT_MAX+1. So, the C-index +** ranges from 0, which encodes to -1, to INT_MAX, which encodes to +** INT_MIN. The size of the hash part is limited by the maximum power of +** two that fits in a signed integer; that is (INT_MAX+1)/2. So, it is +** safe to add HFIRSTNODE to any index there.) +*/ + + +/* +** The array part of a table is represented by an inverted array of +** values followed by an array of tags, to avoid wasting space with +** padding. In between them there is an unsigned int, explained later. +** The 'array' pointer points between the two arrays, so that values are +** indexed with negative indices and tags with non-negative indices. + + Values Tags + -------------------------------------------------------- + ... | Value 1 | Value 0 |unsigned|0|1|... + -------------------------------------------------------- + ^ t->array + +** All accesses to 't->array' should be through the macros 'getArrTag' +** and 'getArrVal'. +*/ + +/* Computes the address of the tag for the abstract C-index 'k' */ +#define getArrTag(t,k) (cast(lu_byte*, (t)->array) + sizeof(unsigned) + (k)) + +/* Computes the address of the value for the abstract C-index 'k' */ +#define getArrVal(t,k) ((t)->array - 1 - (k)) + + +/* +** The unsigned between the two arrays is used as a hint for #t; +** see luaH_getn. It is stored there to avoid wasting space in +** the structure Table for tables with no array part. +*/ +#define lenhint(t) cast(unsigned*, (t)->array) + + +/* +** Move TValues to/from arrays, using C indices +*/ +#define arr2obj(h,k,val) \ + ((val)->tt_ = *getArrTag(h,(k)), (val)->value_ = *getArrVal(h,(k))) + +#define obj2arr(h,k,val) \ + (*getArrTag(h,(k)) = (val)->tt_, *getArrVal(h,(k)) = (val)->value_) + + +/* +** Often, we need to check the tag of a value before moving it. The +** following macros also move TValues to/from arrays, but receive the +** precomputed tag value or address as an extra argument. +*/ +#define farr2val(h,k,tag,res) \ + ((res)->tt_ = tag, (res)->value_ = *getArrVal(h,(k))) + +#define fval2arr(h,k,tag,val) \ + (*tag = (val)->tt_, *getArrVal(h,(k)) = (val)->value_) + + +LUAI_FUNC lu_byte luaH_get (Table *t, const TValue *key, TValue *res); +LUAI_FUNC lu_byte luaH_getshortstr (Table *t, TString *key, TValue *res); +LUAI_FUNC lu_byte luaH_getstr (Table *t, TString *key, TValue *res); +LUAI_FUNC lu_byte luaH_getint (Table *t, lua_Integer key, TValue *res); + +/* Special get for metamethods */ +LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); + +LUAI_FUNC int luaH_psetint (Table *t, lua_Integer key, TValue *val); +LUAI_FUNC int luaH_psetshortstr (Table *t, TString *key, TValue *val); +LUAI_FUNC int luaH_psetstr (Table *t, TString *key, TValue *val); +LUAI_FUNC int luaH_pset (Table *t, const TValue *key, TValue *val); + LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value); -LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); -LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); -LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); -LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, - TValue *value); LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value); + LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, - const TValue *slot, TValue *value); + TValue *value, int hres); LUAI_FUNC Table *luaH_new (lua_State *L); -LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, - unsigned int nhsize); -LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned nasize, + unsigned nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned nasize); +LUAI_FUNC lu_mem luaH_size (Table *t); LUAI_FUNC void luaH_free (lua_State *L, Table *t); LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); -LUAI_FUNC lua_Unsigned luaH_getn (Table *t); -LUAI_FUNC unsigned int luaH_realasize (const Table *t); +LUAI_FUNC lua_Unsigned luaH_getn (lua_State *L, Table *t); #if defined(LUA_DEBUG) LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); -LUAI_FUNC int luaH_isdummy (const Table *t); #endif diff --git a/source/external/lua/ltablib.c b/source/external/lua/ltablib.c deleted file mode 100644 index d80eb80..0000000 --- a/source/external/lua/ltablib.c +++ /dev/null @@ -1,429 +0,0 @@ -/* -** $Id: ltablib.c $ -** Library for Table Manipulation -** See Copyright Notice in lua.h -*/ - -#define ltablib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -/* -** Operations that an object must define to mimic a table -** (some functions only need some of them) -*/ -#define TAB_R 1 /* read */ -#define TAB_W 2 /* write */ -#define TAB_L 4 /* length */ -#define TAB_RW (TAB_R | TAB_W) /* read/write */ - - -#define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) - - -static int checkfield (lua_State *L, const char *key, int n) { - lua_pushstring(L, key); - return (lua_rawget(L, -n) != LUA_TNIL); -} - - -/* -** Check that 'arg' either is a table or can behave like one (that is, -** has a metatable with the required metamethods) -*/ -static void checktab (lua_State *L, int arg, int what) { - if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ - int n = 1; /* number of elements to pop */ - if (lua_getmetatable(L, arg) && /* must have metatable */ - (!(what & TAB_R) || checkfield(L, "__index", ++n)) && - (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && - (!(what & TAB_L) || checkfield(L, "__len", ++n))) { - lua_pop(L, n); /* pop metatable and tested metamethods */ - } - else - luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ - } -} - - -static int tinsert (lua_State *L) { - lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ - lua_Integer pos; /* where to insert new element */ - switch (lua_gettop(L)) { - case 2: { /* called with only 2 arguments */ - pos = e; /* insert new element at the end */ - break; - } - case 3: { - lua_Integer i; - pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ - /* check whether 'pos' is in [1, e] */ - luaL_argcheck(L, (lua_Unsigned)pos - 1u < (lua_Unsigned)e, 2, - "position out of bounds"); - for (i = e; i > pos; i--) { /* move up elements */ - lua_geti(L, 1, i - 1); - lua_seti(L, 1, i); /* t[i] = t[i - 1] */ - } - break; - } - default: { - return luaL_error(L, "wrong number of arguments to 'insert'"); - } - } - lua_seti(L, 1, pos); /* t[pos] = v */ - return 0; -} - - -static int tremove (lua_State *L) { - lua_Integer size = aux_getn(L, 1, TAB_RW); - lua_Integer pos = luaL_optinteger(L, 2, size); - if (pos != size) /* validate 'pos' if given */ - /* check whether 'pos' is in [1, size + 1] */ - luaL_argcheck(L, (lua_Unsigned)pos - 1u <= (lua_Unsigned)size, 1, - "position out of bounds"); - lua_geti(L, 1, pos); /* result = t[pos] */ - for ( ; pos < size; pos++) { - lua_geti(L, 1, pos + 1); - lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ - } - lua_pushnil(L); - lua_seti(L, 1, pos); /* remove entry t[pos] */ - return 1; -} - - -/* -** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever -** possible, copy in increasing order, which is better for rehashing. -** "possible" means destination after original range, or smaller -** than origin, or copying to another table. -*/ -static int tmove (lua_State *L) { - lua_Integer f = luaL_checkinteger(L, 2); - lua_Integer e = luaL_checkinteger(L, 3); - lua_Integer t = luaL_checkinteger(L, 4); - int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ - checktab(L, 1, TAB_R); - checktab(L, tt, TAB_W); - if (e >= f) { /* otherwise, nothing to move */ - lua_Integer n, i; - 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 > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { - for (i = 0; i < n; i++) { - lua_geti(L, 1, f + i); - lua_seti(L, tt, t + i); - } - } - else { - for (i = n - 1; i >= 0; i--) { - lua_geti(L, 1, f + i); - lua_seti(L, tt, t + i); - } - } - } - lua_pushvalue(L, tt); /* return destination table */ - return 1; -} - - -static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { - lua_geti(L, 1, i); - if (l_unlikely(!lua_isstring(L, -1))) - luaL_error(L, "invalid value (%s) at index %I in table for 'concat'", - luaL_typename(L, -1), i); - luaL_addvalue(b); -} - - -static int tconcat (lua_State *L) { - luaL_Buffer b; - lua_Integer last = aux_getn(L, 1, TAB_R); - size_t lsep; - const char *sep = luaL_optlstring(L, 2, "", &lsep); - lua_Integer i = luaL_optinteger(L, 3, 1); - last = luaL_optinteger(L, 4, last); - luaL_buffinit(L, &b); - for (; i < last; i++) { - addfield(L, &b, i); - luaL_addlstring(&b, sep, lsep); - } - if (i == last) /* add last value (if interval was not empty) */ - addfield(L, &b, i); - luaL_pushresult(&b); - return 1; -} - - -/* -** {====================================================== -** Pack/unpack -** ======================================================= -*/ - -static int tpack (lua_State *L) { - int i; - int n = lua_gettop(L); /* number of elements to pack */ - lua_createtable(L, n, 1); /* create result table */ - lua_insert(L, 1); /* put it at index 1 */ - for (i = n; i >= 1; i--) /* assign elements */ - lua_seti(L, 1, i); - lua_pushinteger(L, n); - lua_setfield(L, 1, "n"); /* t.n = number of elements */ - return 1; /* return table */ -} - - -static int tunpack (lua_State *L) { - lua_Unsigned n; - lua_Integer i = luaL_optinteger(L, 2, 1); - lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); - if (i > e) return 0; /* empty range */ - n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ - if (l_unlikely(n >= (unsigned int)INT_MAX || - !lua_checkstack(L, (int)(++n)))) - return luaL_error(L, "too many results to unpack"); - for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ - lua_geti(L, 1, i); - } - lua_geti(L, 1, e); /* push last element */ - return (int)n; -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** Quicksort -** (based on 'Algorithms in MODULA-3', Robert Sedgewick; -** Addison-Wesley, 1993.) -** ======================================================= -*/ - - -/* type for array indices */ -typedef unsigned int IdxT; - - -/* -** Produce a "random" 'unsigned int' to randomize pivot choice. This -** macro is used only when 'sort' detects a big imbalance in the result -** of a partition. (If you don't want/need this "randomness", ~0 is a -** good choice.) -*/ -#if !defined(l_randomizePivot) /* { */ - -#include - -/* size of 'e' measured in number of 'unsigned int's */ -#define sof(e) (sizeof(e) / sizeof(unsigned int)) - -/* -** Use 'time' and 'clock' as sources of "randomness". Because we don't -** know the types 'clock_t' and 'time_t', we cannot cast them to -** anything without risking overflows. A safe way to use their values -** is to copy them to an array of a known type and use the array values. -*/ -static unsigned int l_randomizePivot (void) { - clock_t c = clock(); - time_t t = time(NULL); - unsigned int buff[sof(c) + sof(t)]; - unsigned int i, rnd = 0; - memcpy(buff, &c, sof(c) * sizeof(unsigned int)); - memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); - for (i = 0; i < sof(buff); i++) - rnd += buff[i]; - return rnd; -} - -#endif /* } */ - - -/* arrays larger than 'RANLIMIT' may use randomized pivots */ -#define RANLIMIT 100u - - -static void set2 (lua_State *L, IdxT i, IdxT j) { - lua_seti(L, 1, i); - lua_seti(L, 1, j); -} - - -/* -** Return true iff value at stack index 'a' is less than the value at -** index 'b' (according to the order of the sort). -*/ -static int sort_comp (lua_State *L, int a, int b) { - if (lua_isnil(L, 2)) /* no function? */ - return lua_compare(L, a, b, LUA_OPLT); /* a < b */ - else { /* function */ - int res; - lua_pushvalue(L, 2); /* push function */ - lua_pushvalue(L, a-1); /* -1 to compensate function */ - lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ - lua_call(L, 2, 1); /* call function */ - res = lua_toboolean(L, -1); /* get result */ - lua_pop(L, 1); /* pop result */ - return res; - } -} - - -/* -** Does the partition: Pivot P is at the top of the stack. -** precondition: a[lo] <= P == a[up-1] <= a[up], -** so it only needs to do the partition from lo + 1 to up - 2. -** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] -** returns 'i'. -*/ -static IdxT partition (lua_State *L, IdxT lo, IdxT up) { - IdxT i = lo; /* will be incremented before first use */ - IdxT j = up - 1; /* will be decremented before first use */ - /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ - for (;;) { - /* next loop: repeat ++i while a[i] < P */ - while ((void)lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { - if (l_unlikely(i == up - 1)) /* a[i] < P but a[up - 1] == P ?? */ - luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[i] */ - } - /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ - /* next loop: repeat --j while P < a[j] */ - while ((void)lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { - if (l_unlikely(j < i)) /* j < i but a[j] > P ?? */ - luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[j] */ - } - /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ - if (j < i) { /* no elements out of place? */ - /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ - lua_pop(L, 1); /* pop a[j] */ - /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ - set2(L, up - 1, i); - return i; - } - /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ - set2(L, i, j); - } -} - - -/* -** Choose an element in the middle (2nd-3th quarters) of [lo,up] -** "randomized" by 'rnd' -*/ -static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { - IdxT r4 = (up - lo) / 4; /* range/4 */ - IdxT p = rnd % (r4 * 2) + (lo + r4); - lua_assert(lo + r4 <= p && p <= up - r4); - return p; -} - - -/* -** Quicksort algorithm (recursive function) -*/ -static void auxsort (lua_State *L, IdxT lo, IdxT up, - unsigned int rnd) { - while (lo < up) { /* loop for tail recursion */ - IdxT p; /* Pivot index */ - IdxT n; /* to be used later */ - /* sort elements 'lo', 'p', and 'up' */ - lua_geti(L, 1, lo); - lua_geti(L, 1, up); - if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ - set2(L, lo, up); /* swap a[lo] - a[up] */ - else - lua_pop(L, 2); /* remove both values */ - if (up - lo == 1) /* only 2 elements? */ - return; /* already sorted */ - if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ - p = (lo + up)/2; /* middle element is a good pivot */ - else /* for larger intervals, it is worth a random pivot */ - p = choosePivot(lo, up, rnd); - lua_geti(L, 1, p); - lua_geti(L, 1, lo); - if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ - set2(L, p, lo); /* swap a[p] - a[lo] */ - else { - lua_pop(L, 1); /* remove a[lo] */ - lua_geti(L, 1, up); - if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ - set2(L, p, up); /* swap a[up] - a[p] */ - else - lua_pop(L, 2); - } - if (up - lo == 2) /* only 3 elements? */ - return; /* already sorted */ - lua_geti(L, 1, p); /* get middle element (Pivot) */ - lua_pushvalue(L, -1); /* push Pivot */ - lua_geti(L, 1, up - 1); /* push a[up - 1] */ - set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ - p = partition(L, lo, up); - /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ - if (p - lo < up - p) { /* lower interval is smaller? */ - auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ - n = p - lo; /* size of smaller interval */ - lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ - } - else { - auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ - n = up - p; /* size of smaller interval */ - up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ - } - if ((up - lo) / 128 > n) /* partition too imbalanced? */ - rnd = l_randomizePivot(); /* try a new randomization */ - } /* tail call auxsort(L, lo, up, rnd) */ -} - - -static int sort (lua_State *L) { - lua_Integer n = aux_getn(L, 1, TAB_RW); - if (n > 1) { /* non-trivial interval? */ - luaL_argcheck(L, n < INT_MAX, 1, "array too big"); - if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ - lua_settop(L, 2); /* make sure there are two arguments */ - auxsort(L, 1, (IdxT)n, 0); - } - return 0; -} - -/* }====================================================== */ - - -static const luaL_Reg tab_funcs[] = { - {"concat", tconcat}, - {"insert", tinsert}, - {"pack", tpack}, - {"unpack", tunpack}, - {"remove", tremove}, - {"move", tmove}, - {"sort", sort}, - {NULL, NULL} -}; - - -LUAMOD_API int luaopen_table (lua_State *L) { - luaL_newlib(L, tab_funcs); - return 1; -} - diff --git a/source/external/lua/ltm.c b/source/external/lua/ltm.c deleted file mode 100644 index b657b78..0000000 --- a/source/external/lua/ltm.c +++ /dev/null @@ -1,271 +0,0 @@ -/* -** $Id: ltm.c $ -** Tag methods -** See Copyright Notice in lua.h -*/ - -#define ltm_c -#define LUA_CORE - -#include "lprefix.h" - - -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lgc.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lvm.h" - - -static const char udatatypename[] = "userdata"; - -LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTYPES] = { - "no value", - "nil", "boolean", udatatypename, "number", - "string", "table", "function", udatatypename, "thread", - "upvalue", "proto" /* these last cases are used for tests only */ -}; - - -void luaT_init (lua_State *L) { - static const char *const luaT_eventname[] = { /* ORDER TM */ - "__index", "__newindex", - "__gc", "__mode", "__len", "__eq", - "__add", "__sub", "__mul", "__mod", "__pow", - "__div", "__idiv", - "__band", "__bor", "__bxor", "__shl", "__shr", - "__unm", "__bnot", "__lt", "__le", - "__concat", "__call", "__close" - }; - int i; - for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); - luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ - } -} - - -/* -** function to be used with macro "fasttm": optimized for absence of -** tag methods -*/ -const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { - const TValue *tm = luaH_getshortstr(events, ename); - lua_assert(event <= TM_EQ); - if (notm(tm)) { /* no tag method? */ - events->flags |= cast_byte(1u<metatable; - break; - case LUA_TUSERDATA: - mt = uvalue(o)->metatable; - break; - default: - mt = G(L)->mt[ttype(o)]; - } - return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); -} - - -/* -** Return the name of the type of an object. For tables and userdata -** with metatable, use their '__name' metafield, if present. -*/ -const char *luaT_objtypename (lua_State *L, const TValue *o) { - Table *mt; - if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || - (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { - const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); - if (ttisstring(name)) /* is '__name' a string? */ - return getstr(tsvalue(name)); /* use it as type name */ - } - return ttypename(ttype(o)); /* else use standard type name */ -} - - -void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, - const TValue *p2, const TValue *p3) { - StkId func = L->top; - setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ - setobj2s(L, func + 1, p1); /* 1st argument */ - setobj2s(L, func + 2, p2); /* 2nd argument */ - setobj2s(L, func + 3, p3); /* 3rd argument */ - L->top = func + 4; - /* metamethod may yield only when called from Lua code */ - if (isLuacode(L->ci)) - luaD_call(L, func, 0); - else - luaD_callnoyield(L, func, 0); -} - - -void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, - const TValue *p2, StkId res) { - ptrdiff_t result = savestack(L, res); - StkId func = L->top; - setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ - setobj2s(L, func + 1, p1); /* 1st argument */ - setobj2s(L, func + 2, p2); /* 2nd argument */ - L->top += 3; - /* metamethod may yield only when called from Lua code */ - if (isLuacode(L->ci)) - luaD_call(L, func, 1); - else - luaD_callnoyield(L, func, 1); - res = restorestack(L, result); - setobjs2s(L, res, --L->top); /* move result to its place */ -} - - -static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, - StkId res, TMS event) { - const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ - if (notm(tm)) - tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ - if (notm(tm)) return 0; - luaT_callTMres(L, tm, p1, p2, res); - return 1; -} - - -void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, - StkId res, TMS event) { - if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { - switch (event) { - case TM_BAND: case TM_BOR: case TM_BXOR: - case TM_SHL: case TM_SHR: case TM_BNOT: { - if (ttisnumber(p1) && ttisnumber(p2)) - luaG_tointerror(L, p1, p2); - else - luaG_opinterror(L, p1, p2, "perform bitwise operation on"); - } - /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ - default: - luaG_opinterror(L, p1, p2, "perform arithmetic on"); - } - } -} - - -void luaT_tryconcatTM (lua_State *L) { - StkId top = L->top; - if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, - TM_CONCAT))) - luaG_concaterror(L, s2v(top - 2), s2v(top - 1)); -} - - -void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, - int flip, StkId res, TMS event) { - if (flip) - luaT_trybinTM(L, p2, p1, res, event); - else - luaT_trybinTM(L, p1, p2, res, event); -} - - -void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, - int flip, StkId res, TMS event) { - TValue aux; - setivalue(&aux, i2); - luaT_trybinassocTM(L, p1, &aux, flip, res, event); -} - - -/* -** Calls an order tag method. -** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old -** behavior: if 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 rtop, event)) /* try original event */ - return !l_isfalse(s2v(L->top)); -#if defined(LUA_COMPAT_LT_LE) - else if (event == TM_LE) { - /* try '!(p2 < p1)' for '(p1 <= p2)' */ - L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ - if (callbinTM(L, p2, p1, L->top, TM_LT)) { - L->ci->callstatus ^= CIST_LEQ; /* clear mark */ - return l_isfalse(s2v(L->top)); - } - /* else error will remove this 'ci'; no need to clear mark */ - } -#endif - luaG_ordererror(L, p1, p2); /* no metamethod found */ - return 0; /* to avoid warnings */ -} - - -int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, - int flip, int isfloat, TMS event) { - TValue aux; const TValue *p2; - if (isfloat) { - setfltvalue(&aux, cast_num(v2)); - } - else - setivalue(&aux, v2); - if (flip) { /* arguments were exchanged? */ - p2 = p1; p1 = &aux; /* correct them */ - } - else - p2 = &aux; - return luaT_callorderTM(L, p1, p2, event); -} - - -void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, - const Proto *p) { - int i; - int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */ - int nextra = actual - nfixparams; /* number of extra arguments */ - ci->u.l.nextraargs = nextra; - luaD_checkstack(L, p->maxstacksize + 1); - /* copy function to the top of the stack */ - setobjs2s(L, L->top++, ci->func); - /* move fixed parameters to the top of the stack */ - for (i = 1; i <= nfixparams; i++) { - setobjs2s(L, L->top++, ci->func + i); - setnilvalue(s2v(ci->func + i)); /* erase original parameter (for GC) */ - } - ci->func += actual + 1; - ci->top += actual + 1; - lua_assert(L->top <= ci->top && ci->top <= L->stack_last); -} - - -void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { - int i; - int nextra = ci->u.l.nextraargs; - if (wanted < 0) { - wanted = nextra; /* get all extra arguments available */ - checkstackGCp(L, nextra, where); /* ensure stack space */ - L->top = where + nextra; /* next instruction will need top */ - } - for (i = 0; i < wanted && i < nextra; i++) - setobjs2s(L, where + i, ci->func - nextra + i); - for (; i < wanted; i++) /* complete required results with nil */ - setnilvalue(s2v(where + i)); -} - diff --git a/source/external/lua/ltm.h b/source/external/lua/ltm.h index 73b833c..07fc8c1 100644 --- a/source/external/lua/ltm.h +++ b/source/external/lua/ltm.h @@ -48,10 +48,10 @@ typedef enum { /* ** Mask with 1 in all fast-access methods. A 1 in any of these bits ** in the flag of a (meta)table means the metatable does not have the -** corresponding metamethod field. (Bit 7 of the flag is used for -** 'isrealasize'.) +** corresponding metamethod field. (Bit 6 of the flag indicates that +** the table is using the dummy node; bit 7 is used for 'isrealasize'.) */ -#define maskflags (~(~0u << (TM_EQ + 1))) +#define maskflags cast_byte(~(~0u << (TM_EQ + 1))) /* @@ -60,11 +60,12 @@ typedef enum { */ #define notm(tm) ttisnil(tm) +#define checknoTM(mt,e) ((mt) == NULL || (mt)->flags & (1u<<(e))) -#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ - ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) +#define gfasttm(g,mt,e) \ + (checknoTM(mt, e) ? NULL : luaT_gettm(mt, e, (g)->tmname[e])) -#define fasttm(l,et,e) gfasttm(G(l), et, e) +#define fasttm(l,mt,e) gfasttm(G(l), mt, e) #define ttypename(x) luaT_typenames_[(x) + 1] @@ -80,8 +81,8 @@ LUAI_FUNC void luaT_init (lua_State *L); LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, const TValue *p2, const TValue *p3); -LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, - const TValue *p1, const TValue *p2, StkId p3); +LUAI_FUNC lu_byte luaT_callTMres (lua_State *L, const TValue *f, + const TValue *p1, const TValue *p2, StkId p3); LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, StkId res, TMS event); LUAI_FUNC void luaT_tryconcatTM (lua_State *L); @@ -94,10 +95,11 @@ LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, int inv, int isfloat, TMS event); -LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, - struct CallInfo *ci, const Proto *p); -LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, - StkId where, int wanted); +LUAI_FUNC void luaT_adjustvarargs (lua_State *L, struct CallInfo *ci, + const Proto *p); +LUAI_FUNC void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc); +LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, StkId where, + int wanted, int vatab); #endif diff --git a/source/external/lua/lua.h b/source/external/lua/lua.h index 820535b..ab473dc 100644 --- a/source/external/lua/lua.h +++ b/source/external/lua/lua.h @@ -1,7 +1,7 @@ /* ** $Id: lua.h $ ** Lua - A Scripting Language -** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** Lua.org, PUC-Rio, Brazil (www.lua.org) ** See Copyright Notice at the end of this file */ @@ -13,22 +13,21 @@ #include -#include "luaconf.h" - - -#define LUA_VERSION_MAJOR "5" -#define LUA_VERSION_MINOR "4" -#define LUA_VERSION_RELEASE "3" - -#define LUA_VERSION_NUM 504 -#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0) - -#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR -#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2021 Lua.org, PUC-Rio" +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2025 Lua.org, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" +#define LUA_VERSION_MAJOR_N 5 +#define LUA_VERSION_MINOR_N 5 +#define LUA_VERSION_RELEASE_N 0 + +#define LUA_VERSION_NUM (LUA_VERSION_MAJOR_N * 100 + LUA_VERSION_MINOR_N) +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + LUA_VERSION_RELEASE_N) + + +#include "luaconf.h" + + /* mark for precompiled code ('Lua') */ #define LUA_SIGNATURE "\x1bLua" @@ -38,10 +37,10 @@ /* ** Pseudo-indices -** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty -** space after that to help overflow detection) +** (The stack size is limited to INT_MAX/2; we keep some free empty +** space after that to help overflow detection.) */ -#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) +#define LUA_REGISTRYINDEX (-(INT_MAX/2 + 1000)) #define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) @@ -81,9 +80,10 @@ typedef struct lua_State lua_State; /* predefined values in the registry */ -#define LUA_RIDX_MAINTHREAD 1 +/* index 1 is reserved for the reference mechanism */ #define LUA_RIDX_GLOBALS 2 -#define LUA_RIDX_LAST LUA_RIDX_GLOBALS +#define LUA_RIDX_MAINTHREAD 3 +#define LUA_RIDX_LAST 3 /* type of numbers in Lua */ @@ -131,6 +131,16 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); +/* +** Type used by the debug API to collect debug information +*/ +typedef struct lua_Debug lua_Debug; + + +/* +** Functions to be called by the debugger in specific events +*/ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); /* @@ -150,10 +160,10 @@ extern const char lua_ident[]; /* ** state manipulation */ -LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud, unsigned seed); LUA_API void (lua_close) (lua_State *L); LUA_API lua_State *(lua_newthread) (lua_State *L); -LUA_API int (lua_resetthread) (lua_State *L); +LUA_API int (lua_closethread) (lua_State *L, lua_State *from); LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); @@ -234,6 +244,8 @@ LUA_API void (lua_pushnil) (lua_State *L); LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len); +LUA_API const char *(lua_pushexternalstring) (lua_State *L, + const char *s, size_t len, lua_Alloc falloc, void *ud); LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp); @@ -313,7 +325,7 @@ LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); /* -** garbage-collection function and options +** garbage-collection options */ #define LUA_GCSTOP 0 @@ -322,11 +334,28 @@ LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); #define LUA_GCCOUNT 3 #define LUA_GCCOUNTB 4 #define LUA_GCSTEP 5 -#define LUA_GCSETPAUSE 6 -#define LUA_GCSETSTEPMUL 7 -#define LUA_GCISRUNNING 9 -#define LUA_GCGEN 10 -#define LUA_GCINC 11 +#define LUA_GCISRUNNING 6 +#define LUA_GCGEN 7 +#define LUA_GCINC 8 +#define LUA_GCPARAM 9 + + +/* +** garbage-collection parameters +*/ +/* parameters for generational mode */ +#define LUA_GCPMINORMUL 0 /* control minor collections */ +#define LUA_GCPMAJORMINOR 1 /* control shift major->minor */ +#define LUA_GCPMINORMAJOR 2 /* control shift minor->major */ + +/* parameters for incremental mode */ +#define LUA_GCPPAUSE 3 /* size of pause between successive GCs */ +#define LUA_GCPSTEPMUL 4 /* GC "speed" */ +#define LUA_GCPSTEPSIZE 5 /* GC granularity */ + +/* number of parameters */ +#define LUA_GCPN 6 + LUA_API int (lua_gc) (lua_State *L, int what, ...); @@ -342,7 +371,9 @@ LUA_API int (lua_next) (lua_State *L, int idx); LUA_API void (lua_concat) (lua_State *L, int n); LUA_API void (lua_len) (lua_State *L, int idx); -LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); +#define LUA_N2SBUFFSZ 64 +LUA_API unsigned (lua_numbertocstring) (lua_State *L, int idx, char *buff); +LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); @@ -401,19 +432,12 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx); ** compatibility macros ** =============================================================== */ -#if defined(LUA_COMPAT_APIINTCASTS) - -#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) -#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) -#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) - -#endif #define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) -#define LUA_NUMTAGS LUA_NUMTYPES +#define lua_resetthread(L) lua_closethread(L,NULL) /* }============================================================== */ @@ -442,12 +466,6 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx); #define LUA_MASKLINE (1 << LUA_HOOKLINE) #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) -typedef struct lua_Debug lua_Debug; /* activation record */ - - -/* Functions to be called by the debugger in specific events */ -typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); - LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); @@ -465,7 +483,6 @@ LUA_API lua_Hook (lua_gethook) (lua_State *L); LUA_API int (lua_gethookmask) (lua_State *L); LUA_API int (lua_gethookcount) (lua_State *L); -LUA_API int (lua_setcstacklimit) (lua_State *L, unsigned int limit); struct lua_Debug { int event; @@ -480,9 +497,10 @@ struct lua_Debug { unsigned char nups; /* (u) number of upvalues */ unsigned char nparams;/* (u) number of parameters */ char isvararg; /* (u) */ + unsigned char extraargs; /* (t) number of extra arguments */ char istailcall; /* (t) */ - unsigned short ftransfer; /* (r) index of first value transferred */ - unsigned short ntransfer; /* (r) number of transferred values */ + int ftransfer; /* (r) index of first value transferred */ + int ntransfer; /* (r) number of transferred values */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ struct CallInfo *i_ci; /* active function */ @@ -491,8 +509,19 @@ struct lua_Debug { /* }====================================================================== */ +#define LUAI_TOSTRAUX(x) #x +#define LUAI_TOSTR(x) LUAI_TOSTRAUX(x) + +#define LUA_VERSION_MAJOR LUAI_TOSTR(LUA_VERSION_MAJOR_N) +#define LUA_VERSION_MINOR LUAI_TOSTR(LUA_VERSION_MINOR_N) +#define LUA_VERSION_RELEASE LUAI_TOSTR(LUA_VERSION_RELEASE_N) + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE + + /****************************************************************************** -* Copyright (C) 1994-2021 Lua.org, PUC-Rio. +* Copyright (C) 1994-2025 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/source/external/lua/lua.hpp b/source/external/lua/lua.hpp index 8f97ef3..2853364 100644 --- a/source/external/lua/lua.hpp +++ b/source/external/lua/lua.hpp @@ -1,9 +1,10 @@ // lua.hpp // Lua header files for C++ -// <> not supplied automatically because Lua also compiles as C++ +// 'extern "C" not supplied automatically in lua.h and other headers +// because Lua also compiles as C++ -//extern "C" { +extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" -//} +} diff --git a/source/external/lua/luaconf.h b/source/external/lua/luaconf.h index e64d2ee..96a7780 100644 --- a/source/external/lua/luaconf.h +++ b/source/external/lua/luaconf.h @@ -58,15 +58,37 @@ #endif +/* +** When POSIX DLL ('LUA_USE_DLOPEN') is enabled, the Lua stand-alone +** application will try to dynamically link a 'readline' facility +** for its REPL. In that case, LUA_READLINELIB is the name of the +** library it will look for those facilities. If lua.c cannot open +** the specified library, it will generate a warning and then run +** without 'readline'. If that macro is not defined, lua.c will not +** use 'readline'. +*/ #if defined(LUA_USE_LINUX) #define LUA_USE_POSIX #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_READLINELIB "libreadline.so" #endif #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX -#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ +#define LUA_USE_DLOPEN /* macOS does not need -ldl */ +#define LUA_READLINELIB "libedit.dylib" +#endif + + +#if defined(LUA_USE_IOS) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN +#endif + + +#if defined(LUA_USE_C89) && defined(LUA_USE_POSIX) +#error "POSIX is not compatible with C89" #endif @@ -116,7 +138,7 @@ /* @@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. */ -#define LUA_32BITS 0 +/* #define LUA_32BITS */ /* @@ -131,7 +153,7 @@ #endif -#if LUA_32BITS /* { */ +#if defined(LUA_32BITS) /* { */ /* ** 32-bit integers and 'float' */ @@ -251,6 +273,15 @@ #endif + +/* +** LUA_IGMARK is a mark to ignore all after it when building the +** module name (e.g., used to build the luaopen_ function name). +** Typically, the suffix after the mark is the module version, +** as in "mod-v1.2.so". +*/ +#define LUA_IGMARK "-" + /* }================================================================== */ @@ -288,32 +319,13 @@ ** More often than not the libs go together with the core. */ #define LUALIB_API LUA_API + +#if defined(__cplusplus) +/* Lua uses the "C name" when calling open functions */ +#define LUAMOD_API extern "C" +#else #define LUAMOD_API LUA_API - - -/* -@@ LUAI_FUNC is a mark for all extern functions that are not to be -** exported to outside modules. -@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables, -** none of which to be exported to outside modules (LUAI_DDEF for -** definitions and LUAI_DDEC for declarations). -** CHANGE them if you need to mark them in some special way. Elf/gcc -** (versions 3.2 and later) mark them as "hidden" to optimize access -** when Lua is compiled as a shared library. Not all elf targets support -** this attribute. Unfortunately, gcc does not offer a way to check -** whether the target offers that support, and those without support -** give a warning about it. To avoid these warnings, change to the -** default definition. -*/ -#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ - defined(__ELF__) /* { */ -#define LUAI_FUNC __attribute__((visibility("internal"))) extern -#else /* }{ */ -#define LUAI_FUNC extern -#endif /* } */ - -#define LUAI_DDEC(dec) LUAI_FUNC dec -#define LUAI_DDEF /* empty */ +#endif /* }================================================================== */ @@ -325,11 +337,10 @@ */ /* -@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. -** You can define it to get all options, or change specific options -** to fit your specific needs. +@@ LUA_COMPAT_GLOBAL avoids 'global' being a reserved word */ -#if defined(LUA_COMPAT_5_3) /* { */ +#define LUA_COMPAT_GLOBAL + /* @@ LUA_COMPAT_MATHLIB controls the presence of several deprecated @@ -337,23 +348,7 @@ ** (These functions were already officially removed in 5.3; ** nevertheless they are still available here.) */ -#define LUA_COMPAT_MATHLIB - -/* -@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for -** manipulating other integer types (lua_pushunsigned, lua_tounsigned, -** luaL_checkint, luaL_checklong, etc.) -** (These macros were also officially removed in 5.3, but they are still -** available here.) -*/ -#define LUA_COMPAT_APIINTCASTS - - -/* -@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod -** using '__lt'. -*/ -#define LUA_COMPAT_LT_LE +/* #define LUA_COMPAT_MATHLIB */ /* @@ -370,8 +365,6 @@ #define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) #define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) -#endif /* } */ - /* }================================================================== */ @@ -390,35 +383,23 @@ @@ l_floatatt(x) corrects float attribute '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. +@@ LUA_NUMBER_FMT is the format for writing floats with the maximum +** number of digits that respects tostring(tonumber(numeral)) == numeral. +** (That would be floor(log10(2^n)), where n is the number of bits in +** the float mantissa.) +@@ LUA_NUMBER_FMT_N is the format for writing floats with the minimum +** number of digits that ensures tonumber(tostring(number)) == number. +** (That would be LUA_NUMBER_FMT+2.) @@ l_mathop allows the addition of an 'l' or 'f' to all math operations. @@ l_floor takes the floor of a float. @@ lua_str2number converts a decimal numeral to a number. */ -/* The following definitions are good for most cases here */ +/* The following definition is good for most cases here */ #define l_floor(x) (l_mathop(floor)(x)) -#define lua_number2str(s,sz,n) \ - l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) - -/* -@@ lua_numbertointeger converts a float number with an integral value -** to an integer, or returns 0 if float is not within the range of -** a lua_Integer. (The range comparisons are tricky because of -** rounding. The tests here assume a two-complement representation, -** where MININTEGER always has an exact representation as a float; -** MAXINTEGER may not have one, and therefore its conversion to float -** may have an ill-defined value.) -*/ -#define lua_numbertointeger(n,p) \ - ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ - (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ - (*(p) = (LUA_INTEGER)(n), 1)) - /* now the variable definitions */ @@ -432,6 +413,7 @@ #define LUA_NUMBER_FRMLEN "" #define LUA_NUMBER_FMT "%.7g" +#define LUA_NUMBER_FMT_N "%.9g" #define l_mathop(op) op##f @@ -448,6 +430,7 @@ #define LUA_NUMBER_FRMLEN "L" #define LUA_NUMBER_FMT "%.19Lg" +#define LUA_NUMBER_FMT_N "%.21Lg" #define l_mathop(op) op##l @@ -462,7 +445,8 @@ #define LUAI_UACNUMBER double #define LUA_NUMBER_FRMLEN "" -#define LUA_NUMBER_FMT "%.14g" +#define LUA_NUMBER_FMT "%.15g" +#define LUA_NUMBER_FMT_N "%.17g" #define l_mathop(op) op @@ -485,7 +469,6 @@ @@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. @@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. @@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. -@@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED. @@ lua_integer2str converts an integer to a string. */ @@ -506,9 +489,6 @@ #define LUA_UNSIGNED unsigned LUAI_UACINT -#define LUA_UNSIGNEDBITS (sizeof(LUA_UNSIGNED) * CHAR_BIT) - - /* now the variable definitions */ #if LUA_INT_TYPE == LUA_INT_INT /* { int */ @@ -680,13 +660,6 @@ #endif -#if defined(LUA_CORE) || defined(LUA_LIB) -/* shorter names for Lua's own use */ -#define l_likely(x) luai_likely(x) -#define l_unlikely(x) luai_unlikely(x) -#endif - - /* }================================================================== */ @@ -711,10 +684,7 @@ @@ 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 +/* #define LUA_USE_APICHECK */ /* }================================================================== */ @@ -727,20 +697,6 @@ ** ===================================================================== */ -/* -@@ LUAI_MAXSTACK limits the size of the Lua stack. -** CHANGE it if you need a different limit. This limit is arbitrary; -** its only purpose is to stop Lua from consuming unlimited stack -** space (and to reserve some numbers for pseudo-indices). -** (It must fit into max(size_t)/32.) -*/ -#if LUAI_IS32INT -#define LUAI_MAXSTACK 1000000 -#else -#define LUAI_MAXSTACK 15000 -#endif - - /* @@ LUA_EXTRASPACE defines the size of a raw memory area associated with ** a Lua state with very fast access. @@ -751,14 +707,15 @@ /* @@ LUA_IDSIZE gives the maximum size for the description of the source -@@ of a function in debug information. +** of a function in debug information. ** CHANGE it if you want a different size. */ #define LUA_IDSIZE 60 /* -@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +@@ LUAL_BUFFERSIZE is the initial buffer size used by the lauxlib +** buffer system. */ #define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number))) @@ -784,7 +741,5 @@ - - #endif diff --git a/source/external/lua/lualib.h b/source/external/lua/lualib.h index 2625529..068f60a 100644 --- a/source/external/lua/lualib.h +++ b/source/external/lua/lualib.h @@ -14,39 +14,52 @@ /* version suffix for environment variable names */ #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR - +#define LUA_GLIBK 1 LUAMOD_API int (luaopen_base) (lua_State *L); -#define LUA_COLIBNAME "coroutine" -LUAMOD_API int (luaopen_coroutine) (lua_State *L); - -#define LUA_TABLIBNAME "table" -LUAMOD_API int (luaopen_table) (lua_State *L); - -#define LUA_IOLIBNAME "io" -LUAMOD_API int (luaopen_io) (lua_State *L); - -#define LUA_OSLIBNAME "os" -LUAMOD_API int (luaopen_os) (lua_State *L); - -#define LUA_STRLIBNAME "string" -LUAMOD_API int (luaopen_string) (lua_State *L); - -#define LUA_UTF8LIBNAME "utf8" -LUAMOD_API int (luaopen_utf8) (lua_State *L); - -#define LUA_MATHLIBNAME "math" -LUAMOD_API int (luaopen_math) (lua_State *L); - -#define LUA_DBLIBNAME "debug" -LUAMOD_API int (luaopen_debug) (lua_State *L); - #define LUA_LOADLIBNAME "package" +#define LUA_LOADLIBK (LUA_GLIBK << 1) LUAMOD_API int (luaopen_package) (lua_State *L); -/* open all previous libraries */ -LUALIB_API void (luaL_openlibs) (lua_State *L); +#define LUA_COLIBNAME "coroutine" +#define LUA_COLIBK (LUA_LOADLIBK << 1) +LUAMOD_API int (luaopen_coroutine) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +#define LUA_DBLIBK (LUA_COLIBK << 1) +LUAMOD_API int (luaopen_debug) (lua_State *L); + +#define LUA_IOLIBNAME "io" +#define LUA_IOLIBK (LUA_DBLIBK << 1) +LUAMOD_API int (luaopen_io) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +#define LUA_MATHLIBK (LUA_IOLIBK << 1) +LUAMOD_API int (luaopen_math) (lua_State *L); + +#define LUA_OSLIBNAME "os" +#define LUA_OSLIBK (LUA_MATHLIBK << 1) +LUAMOD_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +#define LUA_STRLIBK (LUA_OSLIBK << 1) +LUAMOD_API int (luaopen_string) (lua_State *L); + +#define LUA_TABLIBNAME "table" +#define LUA_TABLIBK (LUA_STRLIBK << 1) +LUAMOD_API int (luaopen_table) (lua_State *L); + +#define LUA_UTF8LIBNAME "utf8" +#define LUA_UTF8LIBK (LUA_TABLIBK << 1) +LUAMOD_API int (luaopen_utf8) (lua_State *L); + + +/* open selected libraries */ +LUALIB_API void (luaL_openselectedlibs) (lua_State *L, int load, int preload); + +/* open all libraries */ +#define luaL_openlibs(L) luaL_openselectedlibs(L, ~0, 0) #endif diff --git a/source/external/lua/lundump.c b/source/external/lua/lundump.c deleted file mode 100644 index 5aa55c4..0000000 --- a/source/external/lua/lundump.c +++ /dev/null @@ -1,333 +0,0 @@ -/* -** $Id: lundump.c $ -** load precompiled Lua chunks -** See Copyright Notice in lua.h -*/ - -#define lundump_c -#define LUA_CORE - -#include "lprefix.h" - - -#include -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lmem.h" -#include "lobject.h" -#include "lstring.h" -#include "lundump.h" -#include "lzio.h" - - -#if !defined(luai_verifycode) -#define luai_verifycode(L,f) /* empty */ -#endif - - -typedef struct { - lua_State *L; - ZIO *Z; - const char *name; -} LoadState; - - -static l_noret error (LoadState *S, const char *why) { - luaO_pushfstring(S->L, "%s: bad binary format (%s)", S->name, why); - luaD_throw(S->L, LUA_ERRSYNTAX); -} - - -/* -** All high-level loads go through loadVector; you can change it to -** adapt to the endianness of the input -*/ -#define loadVector(S,b,n) loadBlock(S,b,(n)*sizeof((b)[0])) - -static void loadBlock (LoadState *S, void *b, size_t size) { - if (luaZ_read(S->Z, b, size) != 0) - error(S, "truncated chunk"); -} - - -#define loadVar(S,x) loadVector(S,&x,1) - - -static lu_byte loadByte (LoadState *S) { - int b = zgetc(S->Z); - if (b == EOZ) - error(S, "truncated chunk"); - return cast_byte(b); -} - - -static size_t loadUnsigned (LoadState *S, size_t limit) { - size_t x = 0; - int b; - limit >>= 7; - do { - b = loadByte(S); - if (x >= limit) - error(S, "integer overflow"); - x = (x << 7) | (b & 0x7f); - } while ((b & 0x80) == 0); - return x; -} - - -static size_t loadSize (LoadState *S) { - return loadUnsigned(S, ~(size_t)0); -} - - -static int loadInt (LoadState *S) { - return cast_int(loadUnsigned(S, INT_MAX)); -} - - -static lua_Number loadNumber (LoadState *S) { - lua_Number x; - loadVar(S, x); - return x; -} - - -static lua_Integer loadInteger (LoadState *S) { - lua_Integer x; - loadVar(S, x); - return x; -} - - -/* -** Load a nullable string into prototype 'p'. -*/ -static TString *loadStringN (LoadState *S, Proto *p) { - lua_State *L = S->L; - TString *ts; - size_t size = loadSize(S); - if (size == 0) /* no string? */ - return NULL; - else if (--size <= LUAI_MAXSHORTLEN) { /* short string? */ - char buff[LUAI_MAXSHORTLEN]; - loadVector(S, buff, size); /* load string into buffer */ - ts = luaS_newlstr(L, buff, size); /* create string */ - } - else { /* long string */ - ts = luaS_createlngstrobj(L, size); /* create string */ - setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */ - luaD_inctop(L); - loadVector(S, getstr(ts), size); /* load directly in final place */ - L->top--; /* pop string */ - } - luaC_objbarrier(L, p, ts); - return ts; -} - - -/* -** Load a non-nullable string into prototype 'p'. -*/ -static TString *loadString (LoadState *S, Proto *p) { - TString *st = loadStringN(S, p); - if (st == NULL) - error(S, "bad format for constant string"); - return st; -} - - -static void loadCode (LoadState *S, Proto *f) { - int n = loadInt(S); - f->code = luaM_newvectorchecked(S->L, n, Instruction); - f->sizecode = n; - loadVector(S, f->code, n); -} - - -static void loadFunction(LoadState *S, Proto *f, TString *psource); - - -static void loadConstants (LoadState *S, Proto *f) { - int i; - int n = loadInt(S); - f->k = luaM_newvectorchecked(S->L, n, TValue); - f->sizek = n; - for (i = 0; i < n; i++) - setnilvalue(&f->k[i]); - for (i = 0; i < n; i++) { - TValue *o = &f->k[i]; - int t = loadByte(S); - switch (t) { - case LUA_VNIL: - setnilvalue(o); - break; - case LUA_VFALSE: - setbfvalue(o); - break; - case LUA_VTRUE: - setbtvalue(o); - break; - case LUA_VNUMFLT: - setfltvalue(o, loadNumber(S)); - break; - case LUA_VNUMINT: - setivalue(o, loadInteger(S)); - break; - case LUA_VSHRSTR: - case LUA_VLNGSTR: - setsvalue2n(S->L, o, loadString(S, f)); - break; - default: lua_assert(0); - } - } -} - - -static void loadProtos (LoadState *S, Proto *f) { - int i; - int n = loadInt(S); - f->p = luaM_newvectorchecked(S->L, n, Proto *); - 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); - luaC_objbarrier(S->L, f, f->p[i]); - loadFunction(S, f->p[i], f->source); - } -} - - -/* -** Load the upvalues for a function. The names must be filled first, -** because the filling of the other fields can raise read errors and -** the creation of the error message can call an emergency collection; -** in that case all prototypes must be consistent for the GC. -*/ -static void loadUpvalues (LoadState *S, Proto *f) { - int i, n; - n = loadInt(S); - f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); - f->sizeupvalues = n; - for (i = 0; i < n; i++) /* make array valid for GC */ - f->upvalues[i].name = NULL; - for (i = 0; i < n; i++) { /* following calls can raise errors */ - f->upvalues[i].instack = loadByte(S); - f->upvalues[i].idx = loadByte(S); - f->upvalues[i].kind = loadByte(S); - } -} - - -static void loadDebug (LoadState *S, Proto *f) { - int i, n; - n = loadInt(S); - f->lineinfo = luaM_newvectorchecked(S->L, n, ls_byte); - f->sizelineinfo = n; - loadVector(S, f->lineinfo, n); - n = loadInt(S); - f->abslineinfo = luaM_newvectorchecked(S->L, n, AbsLineInfo); - f->sizeabslineinfo = n; - for (i = 0; i < n; i++) { - f->abslineinfo[i].pc = loadInt(S); - f->abslineinfo[i].line = loadInt(S); - } - n = loadInt(S); - f->locvars = luaM_newvectorchecked(S->L, n, LocVar); - f->sizelocvars = n; - for (i = 0; i < n; i++) - f->locvars[i].varname = NULL; - for (i = 0; i < n; i++) { - f->locvars[i].varname = loadStringN(S, f); - f->locvars[i].startpc = loadInt(S); - f->locvars[i].endpc = loadInt(S); - } - n = loadInt(S); - for (i = 0; i < n; i++) - f->upvalues[i].name = loadStringN(S, f); -} - - -static void loadFunction (LoadState *S, Proto *f, TString *psource) { - f->source = loadStringN(S, f); - if (f->source == NULL) /* no source in dump? */ - f->source = psource; /* reuse parent's source */ - f->linedefined = loadInt(S); - f->lastlinedefined = loadInt(S); - f->numparams = loadByte(S); - f->is_vararg = loadByte(S); - f->maxstacksize = loadByte(S); - loadCode(S, f); - loadConstants(S, f); - loadUpvalues(S, f); - loadProtos(S, f); - loadDebug(S, f); -} - - -static void checkliteral (LoadState *S, const char *s, const char *msg) { - char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ - size_t len = strlen(s); - loadVector(S, buff, len); - if (memcmp(s, buff, len) != 0) - error(S, msg); -} - - -static void fchecksize (LoadState *S, size_t size, const char *tname) { - if (loadByte(S) != size) - error(S, luaO_pushfstring(S->L, "%s size mismatch", tname)); -} - - -#define checksize(S,t) fchecksize(S,sizeof(t),#t) - -static void checkHeader (LoadState *S) { - /* skip 1st char (already read and checked) */ - checkliteral(S, &LUA_SIGNATURE[1], "not a binary chunk"); - if (loadByte(S) != LUAC_VERSION) - error(S, "version mismatch"); - if (loadByte(S) != LUAC_FORMAT) - error(S, "format mismatch"); - checkliteral(S, LUAC_DATA, "corrupted chunk"); - checksize(S, Instruction); - checksize(S, lua_Integer); - checksize(S, lua_Number); - if (loadInteger(S) != LUAC_INT) - error(S, "integer format mismatch"); - if (loadNumber(S) != LUAC_NUM) - error(S, "float format mismatch"); -} - - -/* -** Load precompiled chunk. -*/ -LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) { - LoadState S; - LClosure *cl; - if (*name == '@' || *name == '=') - S.name = name + 1; - else if (*name == LUA_SIGNATURE[0]) - S.name = "binary string"; - else - S.name = name; - S.L = L; - S.Z = Z; - checkHeader(&S); - cl = luaF_newLclosure(L, loadByte(&S)); - setclLvalue2s(L, L->top, cl); - luaD_inctop(L); - cl->p = luaF_newproto(L); - luaC_objbarrier(L, cl, cl->p); - loadFunction(&S, cl->p, NULL); - lua_assert(cl->nupvalues == cl->p->sizeupvalues); - luai_verifycode(L, cl->p); - return cl; -} - diff --git a/source/external/lua/lundump.h b/source/external/lua/lundump.h index f3748a9..c4e06f9 100644 --- a/source/external/lua/lundump.h +++ b/source/external/lua/lundump.h @@ -7,6 +7,8 @@ #ifndef lundump_h #define lundump_h +#include + #include "llimits.h" #include "lobject.h" #include "lzio.h" @@ -15,19 +17,21 @@ /* data to catch conversion errors */ #define LUAC_DATA "\x19\x93\r\n\x1a\n" -#define LUAC_INT 0x5678 -#define LUAC_NUM cast_num(370.5) +#define LUAC_INT -0x5678 +#define LUAC_INST 0x12345678 +#define LUAC_NUM cast_num(-370.5) /* ** Encode major-minor version in one byte, one nibble for each */ -#define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ -#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) +#define LUAC_VERSION (LUA_VERSION_MAJOR_N*16+LUA_VERSION_MINOR_N) #define LUAC_FORMAT 0 /* this is the official format */ + /* load one chunk; from lundump.c */ -LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); +LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name, + int fixed); /* dump one chunk; from ldump.c */ LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, diff --git a/source/external/lua/lutf8lib.c b/source/external/lua/lutf8lib.c deleted file mode 100644 index 901d985..0000000 --- a/source/external/lua/lutf8lib.c +++ /dev/null @@ -1,289 +0,0 @@ -/* -** $Id: lutf8lib.c $ -** Standard library for UTF-8 manipulation -** See Copyright Notice in lua.h -*/ - -#define lutf8lib_c -#define LUA_LIB - -#include "lprefix.h" - - -#include -#include -#include -#include - -#include "lua.h" - -#include "lauxlib.h" -#include "lualib.h" - - -#define MAXUNICODE 0x10FFFFu - -#define MAXUTF 0x7FFFFFFFu - -/* -** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits. -*/ -#if (UINT_MAX >> 30) >= 1 -typedef unsigned int utfint; -#else -typedef unsigned long utfint; -#endif - - -#define iscont(p) ((*(p) & 0xC0) == 0x80) - - -/* from strlib */ -/* translate a relative string position: negative means back from end */ -static lua_Integer u_posrelat (lua_Integer pos, size_t len) { - if (pos >= 0) return pos; - else if (0u - (size_t)pos > len) return 0; - else return (lua_Integer)len + pos + 1; -} - - -/* -** Decode one UTF-8 sequence, returning NULL if byte sequence is -** invalid. The array 'limits' stores the minimum value for each -** sequence length, to check for overlong representations. Its first -** entry forces an error for non-ascii bytes with no continuation -** bytes (count == 0). -*/ -static const char *utf8_decode (const char *s, utfint *val, int strict) { - static const utfint limits[] = - {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; - unsigned int c = (unsigned char)s[0]; - utfint res = 0; /* final result */ - if (c < 0x80) /* ascii? */ - res = c; - else { - int count = 0; /* to count number of continuation bytes */ - for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ - unsigned int cc = (unsigned char)s[++count]; /* read next byte */ - if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ - return NULL; /* invalid byte sequence */ - res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ - } - res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ - if (count > 5 || res > MAXUTF || res < limits[count]) - return NULL; /* invalid byte sequence */ - s += count; /* skip continuation bytes read */ - } - if (strict) { - /* check for invalid code points; too large or surrogates */ - if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu)) - return NULL; - } - if (val) *val = res; - return s + 1; /* +1 to include first byte */ -} - - -/* -** utf8len(s [, i [, j [, lax]]]) --> number of characters that -** start in the range [i,j], or nil + current position if 's' is not -** well formed in that interval -*/ -static int utflen (lua_State *L) { - lua_Integer n = 0; /* counter for the number of characters */ - size_t len; /* string length in bytes */ - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); - lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); - int lax = lua_toboolean(L, 4); - luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, - "initial position out of bounds"); - luaL_argcheck(L, --posj < (lua_Integer)len, 3, - "final position out of bounds"); - while (posi <= posj) { - const char *s1 = utf8_decode(s + posi, NULL, !lax); - if (s1 == NULL) { /* conversion error? */ - luaL_pushfail(L); /* return fail ... */ - lua_pushinteger(L, posi + 1); /* ... and current position */ - return 2; - } - posi = s1 - s; - n++; - } - lua_pushinteger(L, n); - return 1; -} - - -/* -** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all -** characters that start in the range [i,j] -*/ -static int codepoint (lua_State *L) { - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); - lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); - int lax = lua_toboolean(L, 4); - int n; - const char *se; - luaL_argcheck(L, posi >= 1, 2, "out of bounds"); - luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds"); - if (posi > pose) return 0; /* empty interval; return no values */ - if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ - return luaL_error(L, "string slice too long"); - n = (int)(pose - posi) + 1; /* upper bound for number of returns */ - luaL_checkstack(L, n, "string slice too long"); - n = 0; /* count the number of returns */ - se = s + pose; /* string end */ - for (s += posi - 1; s < se;) { - utfint code; - s = utf8_decode(s, &code, !lax); - if (s == NULL) - return luaL_error(L, "invalid UTF-8 code"); - lua_pushinteger(L, code); - n++; - } - return n; -} - - -static void pushutfchar (lua_State *L, int arg) { - lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg); - luaL_argcheck(L, code <= MAXUTF, arg, "value out of range"); - lua_pushfstring(L, "%U", (long)code); -} - - -/* -** utfchar(n1, n2, ...) -> char(n1)..char(n2)... -*/ -static int utfchar (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - if (n == 1) /* optimize common case of single char */ - pushutfchar(L, 1); - else { - int i; - luaL_Buffer b; - luaL_buffinit(L, &b); - for (i = 1; i <= n; i++) { - pushutfchar(L, i); - luaL_addvalue(&b); - } - luaL_pushresult(&b); - } - return 1; -} - - -/* -** offset(s, n, [i]) -> index where n-th character counting from -** position 'i' starts; 0 means character at 'i'. -*/ -static int byteoffset (lua_State *L) { - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer n = luaL_checkinteger(L, 2); - lua_Integer posi = (n >= 0) ? 1 : len + 1; - posi = u_posrelat(luaL_optinteger(L, 3, posi), len); - luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, - "position out of bounds"); - if (n == 0) { - /* find beginning of current byte sequence */ - while (posi > 0 && iscont(s + posi)) posi--; - } - else { - if (iscont(s + posi)) - return luaL_error(L, "initial position is a continuation byte"); - if (n < 0) { - while (n < 0 && posi > 0) { /* move back */ - do { /* find beginning of previous character */ - posi--; - } while (posi > 0 && iscont(s + posi)); - n++; - } - } - else { - n--; /* do not move for 1st character */ - while (n > 0 && posi < (lua_Integer)len) { - do { /* find beginning of next character */ - posi++; - } while (iscont(s + posi)); /* (cannot pass final '\0') */ - n--; - } - } - } - if (n == 0) /* did it find given character? */ - lua_pushinteger(L, posi + 1); - else /* no such character */ - luaL_pushfail(L); - return 1; -} - - -static int iter_aux (lua_State *L, int strict) { - size_t len; - const char *s = luaL_checklstring(L, 1, &len); - lua_Integer n = lua_tointeger(L, 2) - 1; - if (n < 0) /* first iteration? */ - n = 0; /* start from here */ - else if (n < (lua_Integer)len) { - n++; /* skip current byte */ - while (iscont(s + n)) n++; /* and its continuations */ - } - if (n >= (lua_Integer)len) - return 0; /* no more codepoints */ - else { - utfint code; - const char *next = utf8_decode(s + n, &code, strict); - if (next == NULL) - return luaL_error(L, "invalid UTF-8 code"); - lua_pushinteger(L, n + 1); - lua_pushinteger(L, code); - return 2; - } -} - - -static int iter_auxstrict (lua_State *L) { - return iter_aux(L, 1); -} - -static int iter_auxlax (lua_State *L) { - return iter_aux(L, 0); -} - - -static int iter_codes (lua_State *L) { - int lax = lua_toboolean(L, 2); - luaL_checkstring(L, 1); - lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict); - lua_pushvalue(L, 1); - lua_pushinteger(L, 0); - return 3; -} - - -/* pattern to match a single UTF-8 character */ -#define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" - - -static const luaL_Reg funcs[] = { - {"offset", byteoffset}, - {"codepoint", codepoint}, - {"char", utfchar}, - {"len", utflen}, - {"codes", iter_codes}, - /* placeholders */ - {"charpattern", NULL}, - {NULL, NULL} -}; - - -LUAMOD_API int luaopen_utf8 (lua_State *L) { - luaL_newlib(L, funcs); - lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); - lua_setfield(L, -2, "charpattern"); - return 1; -} - diff --git a/source/external/lua/lvm.c b/source/external/lua/lvm.c deleted file mode 100644 index c9729bc..0000000 --- a/source/external/lua/lvm.c +++ /dev/null @@ -1,1836 +0,0 @@ -/* -** $Id: lvm.c $ -** Lua virtual machine -** See Copyright Notice in lua.h -*/ - -#define lvm_c -#define LUA_CORE - -#include "lprefix.h" - -#include -#include -#include -#include -#include -#include - -#include "lua.h" - -#include "ldebug.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "lvm.h" - - -/* -** By default, use jump tables in the main interpreter loop on gcc -** and compatible compilers. -*/ -#if !defined(LUA_USE_JUMPTABLE) -#if defined(__GNUC__) -#define LUA_USE_JUMPTABLE 1 -#else -#define LUA_USE_JUMPTABLE 0 -#endif -#endif - - - -/* limit for table tag-method chains (to avoid infinite loops) */ -#define MAXTAGLOOP 2000 - - -/* -** 'l_intfitsf' checks whether a given integer is in the range that -** can be converted to a float without rounding. Used in comparisons. -*/ - -/* number of bits in the mantissa of a float */ -#define NBM (l_floatatt(MANT_DIG)) - -/* -** Check whether some integers may not fit in a float, testing 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(long) == 32.) -*/ -#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \ - >> (NBM - (3 * (NBM / 4)))) > 0 - -/* limit for integers that fit in a float */ -#define MAXINTFITSF ((lua_Unsigned)1 << NBM) - -/* check whether 'i' is in the interval [-MAXINTFITSF, MAXINTFITSF] */ -#define l_intfitsf(i) ((MAXINTFITSF + l_castS2U(i)) <= (2 * MAXINTFITSF)) - -#else /* all integers fit in a float precisely */ - -#define l_intfitsf(i) 1 - -#endif - - -/* -** Try to convert a value from string to a number value. -** If the value is not a string or is a string not representing -** a valid numeral (or if coercions from strings to numbers -** are disabled via macro 'cvt2num'), do not modify 'result' -** and return 0. -*/ -static int l_strton (const TValue *obj, TValue *result) { - lua_assert(obj != result); - if (!cvt2num(obj)) /* is object not a string? */ - return 0; - else - return (luaO_str2num(svalue(obj), result) == vslen(obj) + 1); -} - - -/* -** Try to convert a value to a float. The float case is already handled -** by the macro 'tonumber'. -*/ -int luaV_tonumber_ (const TValue *obj, lua_Number *n) { - TValue v; - if (ttisinteger(obj)) { - *n = cast_num(ivalue(obj)); - return 1; - } - else if (l_strton(obj, &v)) { /* string coercible to number? */ - *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ - return 1; - } - else - return 0; /* conversion failed */ -} - - -/* -** try to convert a float to an integer, rounding according to 'mode'. -*/ -int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode) { - lua_Number f = l_floor(n); - if (n != f) { /* not an integral value? */ - if (mode == F2Ieq) return 0; /* fails if mode demands integral value */ - else if (mode == F2Iceil) /* needs ceil? */ - f += 1; /* convert floor to ceil (remember: n != f) */ - } - return lua_numbertointeger(f, p); -} - - -/* -** try to convert a value to an integer, rounding according to 'mode', -** without string coercion. -** ("Fast track" handled by macro 'tointegerns'.) -*/ -int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode) { - if (ttisfloat(obj)) - return luaV_flttointeger(fltvalue(obj), p, mode); - else if (ttisinteger(obj)) { - *p = ivalue(obj); - return 1; - } - else - return 0; -} - - -/* -** try to convert a value to an integer. -*/ -int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode) { - TValue v; - if (l_strton(obj, &v)) /* does 'obj' point to a numerical string? */ - obj = &v; /* change it to point to its corresponding number */ - return luaV_tointegerns(obj, p, mode); -} - - -/* -** Try to convert a 'for' limit to an integer, preserving the semantics -** of the loop. Return true if the loop must not run; otherwise, '*p' -** gets the integer limit. -** (The following explanation assumes a positive step; it is valid for -** negative steps mutatis mutandis.) -** If the limit is an integer or can be converted to an integer, -** rounding down, that is the limit. -** Otherwise, check whether the limit can be converted to a float. If -** the float is too large, clip it to LUA_MAXINTEGER. If the float -** is too negative, the loop should not run, because any initial -** integer value is greater than such limit; so, the function returns -** true to signal that. (For this latter case, no integer limit would be -** correct; even a limit of LUA_MININTEGER would run the loop once for -** an initial value equal to LUA_MININTEGER.) -*/ -static int forlimit (lua_State *L, lua_Integer init, const TValue *lim, - lua_Integer *p, lua_Integer step) { - if (!luaV_tointeger(lim, p, (step < 0 ? F2Iceil : F2Ifloor))) { - /* not coercible to in integer */ - lua_Number flim; /* try to convert to float */ - if (!tonumber(lim, &flim)) /* cannot convert to float? */ - luaG_forerror(L, lim, "limit"); - /* else 'flim' is a float out of integer bounds */ - if (luai_numlt(0, flim)) { /* if it is positive, it is too large */ - if (step < 0) return 1; /* initial value must be less than it */ - *p = LUA_MAXINTEGER; /* truncate */ - } - else { /* it is less than min integer */ - if (step > 0) return 1; /* initial value must be greater than it */ - *p = LUA_MININTEGER; /* truncate */ - } - } - return (step > 0 ? init > *p : init < *p); /* not to run? */ -} - - -/* -** Prepare a numerical for loop (opcode OP_FORPREP). -** Return true to skip the loop. Otherwise, -** after preparation, stack will be as follows: -** ra : internal index (safe copy of the control variable) -** ra + 1 : loop counter (integer loops) or limit (float loops) -** ra + 2 : step -** ra + 3 : control variable -*/ -static int forprep (lua_State *L, StkId ra) { - TValue *pinit = s2v(ra); - TValue *plimit = s2v(ra + 1); - TValue *pstep = s2v(ra + 2); - if (ttisinteger(pinit) && ttisinteger(pstep)) { /* integer loop? */ - lua_Integer init = ivalue(pinit); - lua_Integer step = ivalue(pstep); - lua_Integer limit; - if (step == 0) - luaG_runerror(L, "'for' step is zero"); - setivalue(s2v(ra + 3), init); /* control variable */ - if (forlimit(L, init, plimit, &limit, step)) - return 1; /* skip the loop */ - else { /* prepare loop counter */ - lua_Unsigned count; - if (step > 0) { /* ascending loop? */ - count = l_castS2U(limit) - l_castS2U(init); - if (step != 1) /* avoid division in the too common case */ - count /= l_castS2U(step); - } - else { /* step < 0; descending loop */ - count = l_castS2U(init) - l_castS2U(limit); - /* 'step+1' avoids negating 'mininteger' */ - count /= l_castS2U(-(step + 1)) + 1u; - } - /* store the counter in place of the limit (which won't be - needed anymore) */ - setivalue(plimit, l_castU2S(count)); - } - } - else { /* try making all values floats */ - lua_Number init; lua_Number limit; lua_Number step; - if (l_unlikely(!tonumber(plimit, &limit))) - luaG_forerror(L, plimit, "limit"); - if (l_unlikely(!tonumber(pstep, &step))) - luaG_forerror(L, pstep, "step"); - if (l_unlikely(!tonumber(pinit, &init))) - luaG_forerror(L, pinit, "initial value"); - if (step == 0) - luaG_runerror(L, "'for' step is zero"); - if (luai_numlt(0, step) ? luai_numlt(limit, init) - : luai_numlt(init, limit)) - return 1; /* skip the loop */ - else { - /* make sure internal values are all floats */ - setfltvalue(plimit, limit); - setfltvalue(pstep, step); - setfltvalue(s2v(ra), init); /* internal index */ - setfltvalue(s2v(ra + 3), init); /* control variable */ - } - } - return 0; -} - - -/* -** Execute a step of a float numerical for loop, returning -** true iff the loop must continue. (The integer case is -** written online with opcode OP_FORLOOP, for performance.) -*/ -static int floatforloop (StkId ra) { - lua_Number step = fltvalue(s2v(ra + 2)); - lua_Number limit = fltvalue(s2v(ra + 1)); - lua_Number idx = fltvalue(s2v(ra)); /* internal index */ - idx = luai_numadd(L, idx, step); /* increment index */ - if (luai_numlt(0, step) ? luai_numle(idx, limit) - : luai_numle(limit, idx)) { - chgfltvalue(s2v(ra), idx); /* update internal index */ - setfltvalue(s2v(ra + 3), idx); /* and control variable */ - return 1; /* jump back */ - } - else - return 0; /* finish the loop */ -} - - -/* -** Finish the table access 'val = t[key]'. -** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to -** t[k] entry (which must be empty). -*/ -void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, - const TValue *slot) { - int loop; /* counter to avoid infinite loops */ - const TValue *tm; /* metamethod */ - for (loop = 0; loop < MAXTAGLOOP; loop++) { - if (slot == NULL) { /* 't' is not a table? */ - lua_assert(!ttistable(t)); - tm = luaT_gettmbyobj(L, t, TM_INDEX); - if (l_unlikely(notm(tm))) - luaG_typeerror(L, t, "index"); /* no metamethod */ - /* else will try the metamethod */ - } - else { /* 't' is a table */ - lua_assert(isempty(slot)); - tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ - if (tm == NULL) { /* no metamethod? */ - setnilvalue(s2v(val)); /* result is nil */ - return; - } - /* else will try the metamethod */ - } - if (ttisfunction(tm)) { /* is metamethod a function? */ - luaT_callTMres(L, tm, t, key, val); /* call it */ - return; - } - t = tm; /* else try to access 'tm[key]' */ - if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */ - setobj2s(L, val, slot); /* done */ - return; - } - /* else repeat (tail call 'luaV_finishget') */ - } - luaG_runerror(L, "'__index' chain too long; possible loop"); -} - - -/* -** Finish a table assignment 't[key] = val'. -** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points -** to the entry 't[key]', or to a value with an absent key if there -** is no such entry. (The value at 'slot' must be empty, otherwise -** 'luaV_fastget' would have done the job.) -*/ -void luaV_finishset (lua_State *L, const TValue *t, TValue *key, - TValue *val, const TValue *slot) { - int loop; /* counter to avoid infinite loops */ - for (loop = 0; loop < MAXTAGLOOP; loop++) { - const TValue *tm; /* '__newindex' metamethod */ - if (slot != NULL) { /* is 't' a table? */ - Table *h = hvalue(t); /* save 't' table */ - lua_assert(isempty(slot)); /* slot must be empty */ - tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ - if (tm == NULL) { /* no metamethod? */ - luaH_finishset(L, h, key, slot, val); /* set new value */ - invalidateTMcache(h); - luaC_barrierback(L, obj2gco(h), val); - return; - } - /* else will try the metamethod */ - } - else { /* not a table; check metamethod */ - tm = luaT_gettmbyobj(L, t, TM_NEWINDEX); - if (l_unlikely(notm(tm))) - luaG_typeerror(L, t, "index"); - } - /* try the metamethod */ - if (ttisfunction(tm)) { - luaT_callTM(L, tm, t, key, val); - return; - } - t = tm; /* else repeat assignment over 'tm' */ - if (luaV_fastget(L, t, key, slot, luaH_get)) { - luaV_finishfastset(L, t, slot, val); - return; /* done */ - } - /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ - } - luaG_runerror(L, "'__newindex' chain too long; possible loop"); -} - - -/* -** Compare two strings 'ls' x 'rs', returning an integer less-equal- -** -greater than zero if 'ls' is less-equal-greater than 'rs'. -** The code is a little tricky because it allows '\0' in the strings -** and it uses 'strcoll' (to respect locales) for each segments -** of the strings. -*/ -static int l_strcmp (const TString *ls, const TString *rs) { - const char *l = getstr(ls); - size_t ll = tsslen(ls); - const char *r = getstr(rs); - size_t lr = tsslen(rs); - for (;;) { /* for each segment */ - int temp = strcoll(l, r); - if (temp != 0) /* not equal? */ - return temp; /* done */ - else { /* strings are equal up to a '\0' */ - size_t len = strlen(l); /* index of first '\0' in both strings */ - if (len == lr) /* 'rs' is finished? */ - return (len == ll) ? 0 : 1; /* check 'ls' */ - else if (len == ll) /* 'ls' is finished? */ - return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ - /* both strings longer than 'len'; go on comparing after the '\0' */ - len++; - l += len; ll -= len; r += len; lr -= len; - } - } -} - - -/* -** 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, use the equivalence 'i < f <=> i < ceil(f)'. -** If 'ceil(f)' is out of integer range, either 'f' is greater than -** all integers or less than all integers. -** (The test with 'l_intfitsf' is only for performance; the else -** case is correct for all values, but it is slow due to the conversion -** from float to int.) -** When 'f' is NaN, comparisons must result in false. -*/ -static int LTintfloat (lua_Integer i, lua_Number f) { - if (l_intfitsf(i)) - return luai_numlt(cast_num(i), f); /* compare them as floats */ - else { /* i < f <=> i < ceil(f) */ - lua_Integer fi; - if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ - return i < fi; /* compare them as integers */ - else /* 'f' is either greater or less than all integers */ - return f > 0; /* greater? */ - } -} - - -/* -** 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 (l_intfitsf(i)) - return luai_numle(cast_num(i), f); /* compare them as floats */ - else { /* i <= f <=> i <= floor(f) */ - lua_Integer fi; - if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ - return i <= fi; /* compare them as integers */ - else /* 'f' is either greater or less than all integers */ - return f > 0; /* greater? */ - } -} - - -/* -** Check whether float 'f' is less than integer 'i'. -** See comments on previous function. -*/ -static int LTfloatint (lua_Number f, lua_Integer i) { - if (l_intfitsf(i)) - return luai_numlt(f, cast_num(i)); /* compare them as floats */ - else { /* f < i <=> floor(f) < i */ - lua_Integer fi; - if (luaV_flttointeger(f, &fi, F2Ifloor)) /* fi = floor(f) */ - return fi < i; /* compare them as integers */ - else /* 'f' is either greater or less than all integers */ - return f < 0; /* less? */ - } -} - - -/* -** Check whether float 'f' is less than or equal to integer 'i'. -** See comments on previous function. -*/ -static int LEfloatint (lua_Number f, lua_Integer i) { - if (l_intfitsf(i)) - return luai_numle(f, cast_num(i)); /* compare them as floats */ - else { /* f <= i <=> ceil(f) <= i */ - lua_Integer fi; - if (luaV_flttointeger(f, &fi, F2Iceil)) /* fi = ceil(f) */ - return fi <= i; /* compare them as integers */ - else /* 'f' is either greater or less than all integers */ - return f < 0; /* less? */ - } -} - - -/* -** Return 'l < r', for numbers. -*/ -static int LTnum (const TValue *l, const TValue *r) { - lua_assert(ttisnumber(l) && ttisnumber(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 /* 'l' is float and 'r' is int */ - return LTfloatint(lf, ivalue(r)); - } -} - - -/* -** Return 'l <= r', for numbers. -*/ -static int LEnum (const TValue *l, const TValue *r) { - lua_assert(ttisnumber(l) && ttisnumber(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 /* 'l' is float and 'r' is int */ - return LEfloatint(lf, ivalue(r)); - } -} - - -/* -** return 'l < r' for non-numbers. -*/ -static int lessthanothers (lua_State *L, const TValue *l, const TValue *r) { - lua_assert(!ttisnumber(l) || !ttisnumber(r)); - if (ttisstring(l) && ttisstring(r)) /* both are strings? */ - return l_strcmp(tsvalue(l), tsvalue(r)) < 0; - else - return luaT_callorderTM(L, l, r, TM_LT); -} - - -/* -** Main operation less than; return 'l < r'. -*/ -int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { - if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ - return LTnum(l, r); - else return lessthanothers(L, l, r); -} - - -/* -** return 'l <= r' for non-numbers. -*/ -static int lessequalothers (lua_State *L, const TValue *l, const TValue *r) { - lua_assert(!ttisnumber(l) || !ttisnumber(r)); - if (ttisstring(l) && ttisstring(r)) /* both are strings? */ - return l_strcmp(tsvalue(l), tsvalue(r)) <= 0; - else - return luaT_callorderTM(L, l, r, TM_LE); -} - - -/* -** Main operation less than or equal to; return 'l <= r'. -*/ -int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { - if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */ - return LEnum(l, r); - else return lessequalothers(L, l, r); -} - - -/* -** 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) { - const TValue *tm; - if (ttypetag(t1) != ttypetag(t2)) { /* not the same variant? */ - if (ttype(t1) != ttype(t2) || ttype(t1) != LUA_TNUMBER) - return 0; /* only numbers can be equal with different variants */ - else { /* two numbers with different variants */ - /* One of them is an integer. If the other does not have an - integer value, they cannot be equal; otherwise, compare their - integer values. */ - lua_Integer i1, i2; - return (luaV_tointegerns(t1, &i1, F2Ieq) && - luaV_tointegerns(t2, &i2, F2Ieq) && - i1 == i2); - } - } - /* values have same type and same variant */ - switch (ttypetag(t1)) { - case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: return 1; - case LUA_VNUMINT: return (ivalue(t1) == ivalue(t2)); - case LUA_VNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(t2)); - case LUA_VLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); - case LUA_VLCF: return fvalue(t1) == fvalue(t2); - case LUA_VSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2)); - case LUA_VLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2)); - case LUA_VUSERDATA: { - if (uvalue(t1) == uvalue(t2)) return 1; - else if (L == NULL) return 0; - tm = fasttm(L, uvalue(t1)->metatable, TM_EQ); - if (tm == NULL) - tm = fasttm(L, uvalue(t2)->metatable, TM_EQ); - break; /* will try TM */ - } - case LUA_VTABLE: { - if (hvalue(t1) == hvalue(t2)) return 1; - else if (L == NULL) return 0; - tm = fasttm(L, hvalue(t1)->metatable, TM_EQ); - if (tm == NULL) - tm = fasttm(L, hvalue(t2)->metatable, TM_EQ); - break; /* will try TM */ - } - default: - return gcvalue(t1) == gcvalue(t2); - } - if (tm == NULL) /* no TM? */ - return 0; /* objects are different */ - else { - luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */ - return !l_isfalse(s2v(L->top)); - } -} - - -/* macro used by 'luaV_concat' to ensure that element at 'o' is a string */ -#define tostring(L,o) \ - (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) - -#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) - -/* copy strings in stack from top - n up to top - 1 to buffer */ -static void copy2buff (StkId top, int n, char *buff) { - size_t tl = 0; /* size already copied */ - do { - size_t l = vslen(s2v(top - n)); /* length of string being copied */ - memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char)); - tl += l; - } while (--n > 0); -} - - -/* -** Main operation for concatenation: concat 'total' values in the stack, -** from 'L->top - total' up to 'L->top - 1'. -*/ -void luaV_concat (lua_State *L, int total) { - if (total == 1) - return; /* "all" values already concatenated */ - do { - StkId top = L->top; - int n = 2; /* number of elements handled in this pass (at least 2) */ - if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) || - !tostring(L, s2v(top - 1))) - luaT_tryconcatTM(L); - else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ - cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ - else if (isemptystr(s2v(top - 2))) { /* first operand is 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 = vslen(s2v(top - 1)); - TString *ts; - /* collect total length and number of strings */ - for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { - size_t l = vslen(s2v(top - n - 1)); - if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) - luaG_runerror(L, "string length overflow"); - tl += l; - } - if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ - char buff[LUAI_MAXSHORTLEN]; - copy2buff(top, n, buff); /* copy strings to buffer */ - ts = luaS_newlstr(L, buff, tl); - } - else { /* long string; copy strings directly to final result */ - ts = luaS_createlngstrobj(L, tl); - copy2buff(top, n, getstr(ts)); - } - setsvalue2s(L, top - n, ts); /* create result */ - } - total -= n-1; /* got 'n' strings to create 1 new */ - L->top -= n-1; /* popped 'n' strings and pushed one */ - } while (total > 1); /* repeat until only 1 result left */ -} - - -/* -** Main operation 'ra = #rb'. -*/ -void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { - const TValue *tm; - switch (ttypetag(rb)) { - case LUA_VTABLE: { - Table *h = hvalue(rb); - tm = fasttm(L, h->metatable, TM_LEN); - if (tm) break; /* metamethod? break switch to call it */ - setivalue(s2v(ra), luaH_getn(h)); /* else primitive len */ - return; - } - case LUA_VSHRSTR: { - setivalue(s2v(ra), tsvalue(rb)->shrlen); - return; - } - case LUA_VLNGSTR: { - setivalue(s2v(ra), tsvalue(rb)->u.lnglen); - return; - } - default: { /* try metamethod */ - tm = luaT_gettmbyobj(L, rb, TM_LEN); - if (l_unlikely(notm(tm))) /* no metamethod? */ - luaG_typeerror(L, rb, "get length of"); - break; - } - } - luaT_callTMres(L, tm, rb, rb, ra); -} - - -/* -** Integer division; return 'm // n', that is, floor(m/n). -** C division truncates its result (rounds towards zero). -** 'floor(q) == trunc(q)' when 'q >= 0' or when 'q' is integer, -** otherwise 'floor(q) == trunc(q) - 1'. -*/ -lua_Integer luaV_idiv (lua_State *L, lua_Integer m, lua_Integer n) { - if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ - if (n == 0) - luaG_runerror(L, "attempt to divide by zero"); - return intop(-, 0, m); /* n==-1; avoid overflow with 0x80000...//-1 */ - } - else { - lua_Integer q = m / n; /* perform C division */ - if ((m ^ n) < 0 && m % n != 0) /* 'm/n' would be negative non-integer? */ - q -= 1; /* correct result for different rounding */ - return q; - } -} - - -/* -** Integer modulus; return 'm % n'. (Assume that C '%' with -** negative operands follows C99 behavior. See previous comment -** about luaV_idiv.) -*/ -lua_Integer luaV_mod (lua_State *L, lua_Integer m, lua_Integer n) { - if (l_unlikely(l_castS2U(n) + 1u <= 1u)) { /* special cases: -1 or 0 */ - if (n == 0) - luaG_runerror(L, "attempt to perform 'n%%0'"); - return 0; /* m % -1 == 0; avoid overflow with 0x80000...%-1 */ - } - else { - lua_Integer r = m % n; - if (r != 0 && (r ^ n) < 0) /* 'm/n' would be non-integer negative? */ - r += n; /* correct result for different rounding */ - return r; - } -} - - -/* -** Float modulus -*/ -lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { - lua_Number r; - luai_nummod(L, m, n, r); - return r; -} - - -/* number of bits in an integer */ -#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) - -/* -** Shift left operation. (Shift right just negates 'y'.) -*/ -#define luaV_shiftr(x,y) luaV_shiftl(x,-(y)) - -lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { - if (y < 0) { /* shift right? */ - if (y <= -NBITS) return 0; - else return intop(>>, x, -y); - } - else { /* shift left */ - if (y >= NBITS) return 0; - else return intop(<<, x, y); - } -} - - -/* -** create a new Lua closure, push it in the stack, and initialize -** its upvalues. -*/ -static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, - StkId ra) { - int nup = p->sizeupvalues; - Upvaldesc *uv = p->upvalues; - int i; - LClosure *ncl = luaF_newLclosure(L, nup); - ncl->p = p; - setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */ - for (i = 0; i < nup; i++) { /* fill in its upvalues */ - if (uv[i].instack) /* upvalue refers to local variable? */ - ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx); - else /* get upvalue from enclosing function */ - ncl->upvals[i] = encup[uv[i].idx]; - luaC_objbarrier(L, ncl, ncl->upvals[i]); - } -} - - -/* -** finish execution of an opcode interrupted by a yield -*/ -void luaV_finishOp (lua_State *L) { - CallInfo *ci = L->ci; - StkId base = ci->func + 1; - Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ - OpCode op = GET_OPCODE(inst); - switch (op) { /* finish its execution */ - case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { - setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top); - break; - } - case OP_UNM: case OP_BNOT: case OP_LEN: - case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: - case OP_GETFIELD: case OP_SELF: { - setobjs2s(L, base + GETARG_A(inst), --L->top); - break; - } - case OP_LT: case OP_LE: - case OP_LTI: case OP_LEI: - case OP_GTI: case OP_GEI: - case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */ - int res = !l_isfalse(s2v(L->top - 1)); - L->top--; -#if defined(LUA_COMPAT_LT_LE) - if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */ - ci->callstatus ^= CIST_LEQ; /* clear mark */ - res = !res; /* negate result */ - } -#endif - lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); - if (res != GETARG_k(inst)) /* condition failed? */ - ci->u.l.savedpc++; /* skip jump instruction */ - break; - } - case OP_CONCAT: { - StkId top = L->top - 1; /* top when 'luaT_tryconcatTM' was called */ - int a = GETARG_A(inst); /* first element to concatenate */ - int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */ - setobjs2s(L, top - 2, top); /* put TM result in proper position */ - L->top = top - 1; /* top is one after last element (at top-2) */ - luaV_concat(L, total); /* concat them (may yield again) */ - break; - } - case OP_CLOSE: case OP_RETURN: { /* yielded closing variables */ - ci->u.l.savedpc--; /* repeat instruction to close other vars. */ - break; - } - default: { - /* only these other opcodes can yield */ - lua_assert(op == OP_TFORCALL || op == OP_CALL || - op == OP_TAILCALL || op == OP_SETTABUP || op == OP_SETTABLE || - op == OP_SETI || op == OP_SETFIELD); - break; - } - } -} - - - - -/* -** {================================================================== -** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute' -** =================================================================== -*/ - -#define l_addi(L,a,b) intop(+, a, b) -#define l_subi(L,a,b) intop(-, a, b) -#define l_muli(L,a,b) intop(*, a, b) -#define l_band(a,b) intop(&, a, b) -#define l_bor(a,b) intop(|, a, b) -#define l_bxor(a,b) intop(^, a, b) - -#define l_lti(a,b) (a < b) -#define l_lei(a,b) (a <= b) -#define l_gti(a,b) (a > b) -#define l_gei(a,b) (a >= b) - - -/* -** Arithmetic operations with immediate operands. 'iop' is the integer -** operation, 'fop' is the float operation. -*/ -#define op_arithI(L,iop,fop) { \ - TValue *v1 = vRB(i); \ - int imm = GETARG_sC(i); \ - if (ttisinteger(v1)) { \ - lua_Integer iv1 = ivalue(v1); \ - pc++; setivalue(s2v(ra), iop(L, iv1, imm)); \ - } \ - else if (ttisfloat(v1)) { \ - lua_Number nb = fltvalue(v1); \ - lua_Number fimm = cast_num(imm); \ - pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \ - }} - - -/* -** Auxiliary function for arithmetic operations over floats and others -** with two register operands. -*/ -#define op_arithf_aux(L,v1,v2,fop) { \ - lua_Number n1; lua_Number n2; \ - if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ - pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ - }} - - -/* -** Arithmetic operations over floats and others with register operands. -*/ -#define op_arithf(L,fop) { \ - TValue *v1 = vRB(i); \ - TValue *v2 = vRC(i); \ - op_arithf_aux(L, v1, v2, fop); } - - -/* -** Arithmetic operations with K operands for floats. -*/ -#define op_arithfK(L,fop) { \ - TValue *v1 = vRB(i); \ - TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ - op_arithf_aux(L, v1, v2, fop); } - - -/* -** Arithmetic operations over integers and floats. -*/ -#define op_arith_aux(L,v1,v2,iop,fop) { \ - if (ttisinteger(v1) && ttisinteger(v2)) { \ - lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ - pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ - } \ - else op_arithf_aux(L, v1, v2, fop); } - - -/* -** Arithmetic operations with register operands. -*/ -#define op_arith(L,iop,fop) { \ - TValue *v1 = vRB(i); \ - TValue *v2 = vRC(i); \ - op_arith_aux(L, v1, v2, iop, fop); } - - -/* -** Arithmetic operations with K operands. -*/ -#define op_arithK(L,iop,fop) { \ - TValue *v1 = vRB(i); \ - TValue *v2 = KC(i); lua_assert(ttisnumber(v2)); \ - op_arith_aux(L, v1, v2, iop, fop); } - - -/* -** Bitwise operations with constant operand. -*/ -#define op_bitwiseK(L,op) { \ - TValue *v1 = vRB(i); \ - TValue *v2 = KC(i); \ - lua_Integer i1; \ - lua_Integer i2 = ivalue(v2); \ - if (tointegerns(v1, &i1)) { \ - pc++; setivalue(s2v(ra), op(i1, i2)); \ - }} - - -/* -** Bitwise operations with register operands. -*/ -#define op_bitwise(L,op) { \ - TValue *v1 = vRB(i); \ - TValue *v2 = vRC(i); \ - lua_Integer i1; lua_Integer i2; \ - if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ - pc++; setivalue(s2v(ra), op(i1, i2)); \ - }} - - -/* -** Order operations with register operands. 'opn' actually works -** for all numbers, but the fast track improves performance for -** integers. -*/ -#define op_order(L,opi,opn,other) { \ - int cond; \ - TValue *rb = vRB(i); \ - if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \ - lua_Integer ia = ivalue(s2v(ra)); \ - lua_Integer ib = ivalue(rb); \ - cond = opi(ia, ib); \ - } \ - else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ - cond = opn(s2v(ra), rb); \ - else \ - Protect(cond = other(L, s2v(ra), rb)); \ - docondjump(); } - - -/* -** Order operations with immediate operand. (Immediate operand is -** always small enough to have an exact representation as a float.) -*/ -#define op_orderI(L,opi,opf,inv,tm) { \ - int cond; \ - int im = GETARG_sB(i); \ - if (ttisinteger(s2v(ra))) \ - cond = opi(ivalue(s2v(ra)), im); \ - else if (ttisfloat(s2v(ra))) { \ - lua_Number fa = fltvalue(s2v(ra)); \ - lua_Number fim = cast_num(im); \ - cond = opf(fa, fim); \ - } \ - else { \ - int isf = GETARG_C(i); \ - Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \ - } \ - docondjump(); } - -/* }================================================================== */ - - -/* -** {================================================================== -** Function 'luaV_execute': main interpreter loop -** =================================================================== -*/ - -/* -** some macros for common tasks in 'luaV_execute' -*/ - - -#define RA(i) (base+GETARG_A(i)) -#define RB(i) (base+GETARG_B(i)) -#define vRB(i) s2v(RB(i)) -#define KB(i) (k+GETARG_B(i)) -#define RC(i) (base+GETARG_C(i)) -#define vRC(i) s2v(RC(i)) -#define KC(i) (k+GETARG_C(i)) -#define RKC(i) ((TESTARG_k(i)) ? k + GETARG_C(i) : s2v(base + GETARG_C(i))) - - - -#define updatetrap(ci) (trap = ci->u.l.trap) - -#define updatebase(ci) (base = ci->func + 1) - - -#define updatestack(ci) \ - { if (l_unlikely(trap)) { updatebase(ci); ra = RA(i); } } - - -/* -** Execute a jump instruction. The 'updatetrap' allows signals to stop -** tight loops. (Without it, the local copy of 'trap' could never change.) -*/ -#define dojump(ci,i,e) { pc += GETARG_sJ(i) + e; updatetrap(ci); } - - -/* for test instructions, execute the jump instruction that follows it */ -#define donextjump(ci) { Instruction ni = *pc; dojump(ci, ni, 1); } - -/* -** do a conditional jump: skip next instruction if 'cond' is not what -** was expected (parameter 'k'), else do next instruction, which must -** be a jump. -*/ -#define docondjump() if (cond != GETARG_k(i)) pc++; else donextjump(ci); - - -/* -** Correct global 'pc'. -*/ -#define savepc(L) (ci->u.l.savedpc = pc) - - -/* -** Whenever code can raise errors, the global 'pc' and the global -** 'top' must be correct to report occasional errors. -*/ -#define savestate(L,ci) (savepc(L), L->top = ci->top) - - -/* -** Protect code that, in general, can raise errors, reallocate the -** stack, and change the hooks. -*/ -#define Protect(exp) (savestate(L,ci), (exp), updatetrap(ci)) - -/* special version that does not change the top */ -#define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) - -/* -** Protect code that can only raise errors. (That is, it cannnot change -** the stack or hooks.) -*/ -#define halfProtect(exp) (savestate(L,ci), (exp)) - -/* 'c' is the limit of live values in the stack */ -#define checkGC(L,c) \ - { luaC_condGC(L, (savepc(L), L->top = (c)), \ - updatetrap(ci)); \ - luai_threadyield(L); } - - -/* fetch an instruction and prepare its execution */ -#define vmfetch() { \ - if (l_unlikely(trap)) { /* stack reallocation or hooks? */ \ - trap = luaG_traceexec(L, pc); /* handle hooks */ \ - updatebase(ci); /* correct stack */ \ - } \ - i = *(pc++); \ - ra = RA(i); /* WARNING: any stack reallocation invalidates 'ra' */ \ -} - -#define vmdispatch(o) switch(o) -#define vmcase(l) case l: -#define vmbreak break - - -void luaV_execute (lua_State *L, CallInfo *ci) { - LClosure *cl; - TValue *k; - StkId base; - const Instruction *pc; - int trap; -#if LUA_USE_JUMPTABLE -#include "ljumptab.h" -#endif - startfunc: - trap = L->hookmask; - returning: /* trap already set */ - cl = clLvalue(s2v(ci->func)); - k = cl->p->k; - pc = ci->u.l.savedpc; - if (l_unlikely(trap)) { - if (pc == cl->p->code) { /* first instruction (not resuming)? */ - if (cl->p->is_vararg) - trap = 0; /* hooks will start after VARARGPREP instruction */ - else /* check 'call' hook */ - luaD_hookcall(L, ci); - } - ci->u.l.trap = 1; /* assume trap is on, for now */ - } - base = ci->func + 1; - /* main loop of interpreter */ - for (;;) { - Instruction i; /* instruction being executed */ - StkId ra; /* instruction's A register */ - vmfetch(); -// low-level line tracing for debugging Lua -// printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p))); - lua_assert(base == ci->func + 1); - lua_assert(base <= L->top && L->top < L->stack_last); - /* invalidate top for instructions not expecting it */ - lua_assert(isIT(i) || (cast_void(L->top = base), 1)); - vmdispatch (GET_OPCODE(i)) { - vmcase(OP_MOVE) { - setobjs2s(L, ra, RB(i)); - vmbreak; - } - vmcase(OP_LOADI) { - lua_Integer b = GETARG_sBx(i); - setivalue(s2v(ra), b); - vmbreak; - } - vmcase(OP_LOADF) { - int b = GETARG_sBx(i); - setfltvalue(s2v(ra), cast_num(b)); - vmbreak; - } - vmcase(OP_LOADK) { - TValue *rb = k + GETARG_Bx(i); - setobj2s(L, ra, rb); - vmbreak; - } - vmcase(OP_LOADKX) { - TValue *rb; - rb = k + GETARG_Ax(*pc); pc++; - setobj2s(L, ra, rb); - vmbreak; - } - vmcase(OP_LOADFALSE) { - setbfvalue(s2v(ra)); - vmbreak; - } - vmcase(OP_LFALSESKIP) { - setbfvalue(s2v(ra)); - pc++; /* skip next instruction */ - vmbreak; - } - vmcase(OP_LOADTRUE) { - setbtvalue(s2v(ra)); - vmbreak; - } - vmcase(OP_LOADNIL) { - int b = GETARG_B(i); - do { - setnilvalue(s2v(ra++)); - } while (b--); - vmbreak; - } - vmcase(OP_GETUPVAL) { - int b = GETARG_B(i); - setobj2s(L, ra, cl->upvals[b]->v); - vmbreak; - } - vmcase(OP_SETUPVAL) { - UpVal *uv = cl->upvals[GETARG_B(i)]; - setobj(L, uv->v, s2v(ra)); - luaC_barrier(L, uv, s2v(ra)); - vmbreak; - } - vmcase(OP_GETTABUP) { - const TValue *slot; - TValue *upval = cl->upvals[GETARG_B(i)]->v; - TValue *rc = KC(i); - TString *key = tsvalue(rc); /* key must be a string */ - if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { - setobj2s(L, ra, slot); - } - else - Protect(luaV_finishget(L, upval, rc, ra, slot)); - vmbreak; - } - vmcase(OP_GETTABLE) { - const TValue *slot; - TValue *rb = vRB(i); - TValue *rc = vRC(i); - lua_Unsigned n; - if (ttisinteger(rc) /* fast track for integers? */ - ? (cast_void(n = ivalue(rc)), luaV_fastgeti(L, rb, n, slot)) - : luaV_fastget(L, rb, rc, slot, luaH_get)) { - setobj2s(L, ra, slot); - } - else - Protect(luaV_finishget(L, rb, rc, ra, slot)); - vmbreak; - } - vmcase(OP_GETI) { - const TValue *slot; - TValue *rb = vRB(i); - int c = GETARG_C(i); - if (luaV_fastgeti(L, rb, c, slot)) { - setobj2s(L, ra, slot); - } - else { - TValue key; - setivalue(&key, c); - Protect(luaV_finishget(L, rb, &key, ra, slot)); - } - vmbreak; - } - vmcase(OP_GETFIELD) { - const TValue *slot; - TValue *rb = vRB(i); - TValue *rc = KC(i); - TString *key = tsvalue(rc); /* key must be a string */ - if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { - setobj2s(L, ra, slot); - } - else - Protect(luaV_finishget(L, rb, rc, ra, slot)); - vmbreak; - } - vmcase(OP_SETTABUP) { - const TValue *slot; - TValue *upval = cl->upvals[GETARG_A(i)]->v; - TValue *rb = KB(i); - TValue *rc = RKC(i); - TString *key = tsvalue(rb); /* key must be a string */ - if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { - luaV_finishfastset(L, upval, slot, rc); - } - else - Protect(luaV_finishset(L, upval, rb, rc, slot)); - vmbreak; - } - vmcase(OP_SETTABLE) { - const TValue *slot; - TValue *rb = vRB(i); /* key (table is in 'ra') */ - TValue *rc = RKC(i); /* value */ - lua_Unsigned n; - if (ttisinteger(rb) /* fast track for integers? */ - ? (cast_void(n = ivalue(rb)), luaV_fastgeti(L, s2v(ra), n, slot)) - : luaV_fastget(L, s2v(ra), rb, slot, luaH_get)) { - luaV_finishfastset(L, s2v(ra), slot, rc); - } - else - Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); - vmbreak; - } - vmcase(OP_SETI) { - const TValue *slot; - int c = GETARG_B(i); - TValue *rc = RKC(i); - if (luaV_fastgeti(L, s2v(ra), c, slot)) { - luaV_finishfastset(L, s2v(ra), slot, rc); - } - else { - TValue key; - setivalue(&key, c); - Protect(luaV_finishset(L, s2v(ra), &key, rc, slot)); - } - vmbreak; - } - vmcase(OP_SETFIELD) { - const TValue *slot; - TValue *rb = KB(i); - TValue *rc = RKC(i); - TString *key = tsvalue(rb); /* key must be a string */ - if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { - luaV_finishfastset(L, s2v(ra), slot, rc); - } - else - Protect(luaV_finishset(L, s2v(ra), rb, rc, slot)); - vmbreak; - } - vmcase(OP_NEWTABLE) { - int b = GETARG_B(i); /* log2(hash size) + 1 */ - int c = GETARG_C(i); /* array size */ - Table *t; - if (b > 0) - b = 1 << (b - 1); /* size is 2^(b - 1) */ - lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0)); - if (TESTARG_k(i)) /* non-zero extra argument? */ - c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ - pc++; /* skip extra argument */ - L->top = ra + 1; /* correct top in case of emergency GC */ - t = luaH_new(L); /* memory allocation */ - sethvalue2s(L, ra, t); - if (b != 0 || c != 0) - luaH_resize(L, t, c, b); /* idem */ - checkGC(L, ra + 1); - vmbreak; - } - vmcase(OP_SELF) { - const TValue *slot; - TValue *rb = vRB(i); - TValue *rc = RKC(i); - TString *key = tsvalue(rc); /* key must be a string */ - setobj2s(L, ra + 1, rb); - if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { - setobj2s(L, ra, slot); - } - else - Protect(luaV_finishget(L, rb, rc, ra, slot)); - vmbreak; - } - vmcase(OP_ADDI) { - op_arithI(L, l_addi, luai_numadd); - vmbreak; - } - vmcase(OP_ADDK) { - op_arithK(L, l_addi, luai_numadd); - vmbreak; - } - vmcase(OP_SUBK) { - op_arithK(L, l_subi, luai_numsub); - vmbreak; - } - vmcase(OP_MULK) { - op_arithK(L, l_muli, luai_nummul); - vmbreak; - } - vmcase(OP_MODK) { - op_arithK(L, luaV_mod, luaV_modf); - vmbreak; - } - vmcase(OP_POWK) { - op_arithfK(L, luai_numpow); - vmbreak; - } - vmcase(OP_DIVK) { - op_arithfK(L, luai_numdiv); - vmbreak; - } - vmcase(OP_IDIVK) { - op_arithK(L, luaV_idiv, luai_numidiv); - vmbreak; - } - vmcase(OP_BANDK) { - op_bitwiseK(L, l_band); - vmbreak; - } - vmcase(OP_BORK) { - op_bitwiseK(L, l_bor); - vmbreak; - } - vmcase(OP_BXORK) { - op_bitwiseK(L, l_bxor); - vmbreak; - } - vmcase(OP_SHRI) { - TValue *rb = vRB(i); - int ic = GETARG_sC(i); - lua_Integer ib; - if (tointegerns(rb, &ib)) { - pc++; setivalue(s2v(ra), luaV_shiftl(ib, -ic)); - } - vmbreak; - } - vmcase(OP_SHLI) { - TValue *rb = vRB(i); - int ic = GETARG_sC(i); - lua_Integer ib; - if (tointegerns(rb, &ib)) { - pc++; setivalue(s2v(ra), luaV_shiftl(ic, ib)); - } - vmbreak; - } - vmcase(OP_ADD) { - op_arith(L, l_addi, luai_numadd); - vmbreak; - } - vmcase(OP_SUB) { - op_arith(L, l_subi, luai_numsub); - vmbreak; - } - vmcase(OP_MUL) { - op_arith(L, l_muli, luai_nummul); - vmbreak; - } - vmcase(OP_MOD) { - op_arith(L, luaV_mod, luaV_modf); - vmbreak; - } - vmcase(OP_POW) { - op_arithf(L, luai_numpow); - vmbreak; - } - vmcase(OP_DIV) { /* float division (always with floats) */ - op_arithf(L, luai_numdiv); - vmbreak; - } - vmcase(OP_IDIV) { /* floor division */ - op_arith(L, luaV_idiv, luai_numidiv); - vmbreak; - } - vmcase(OP_BAND) { - op_bitwise(L, l_band); - vmbreak; - } - vmcase(OP_BOR) { - op_bitwise(L, l_bor); - vmbreak; - } - vmcase(OP_BXOR) { - op_bitwise(L, l_bxor); - vmbreak; - } - vmcase(OP_SHR) { - op_bitwise(L, luaV_shiftr); - vmbreak; - } - vmcase(OP_SHL) { - op_bitwise(L, luaV_shiftl); - vmbreak; - } - vmcase(OP_MMBIN) { - Instruction pi = *(pc - 2); /* original arith. expression */ - TValue *rb = vRB(i); - TMS tm = (TMS)GETARG_C(i); - StkId result = RA(pi); - lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR); - Protect(luaT_trybinTM(L, s2v(ra), rb, result, tm)); - vmbreak; - } - vmcase(OP_MMBINI) { - Instruction pi = *(pc - 2); /* original arith. expression */ - int imm = GETARG_sB(i); - TMS tm = (TMS)GETARG_C(i); - int flip = GETARG_k(i); - StkId result = RA(pi); - Protect(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm)); - vmbreak; - } - vmcase(OP_MMBINK) { - Instruction pi = *(pc - 2); /* original arith. expression */ - TValue *imm = KB(i); - TMS tm = (TMS)GETARG_C(i); - int flip = GETARG_k(i); - StkId result = RA(pi); - Protect(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm)); - vmbreak; - } - vmcase(OP_UNM) { - TValue *rb = vRB(i); - lua_Number nb; - if (ttisinteger(rb)) { - lua_Integer ib = ivalue(rb); - setivalue(s2v(ra), intop(-, 0, ib)); - } - else if (tonumberns(rb, nb)) { - setfltvalue(s2v(ra), luai_numunm(L, nb)); - } - else - Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); - vmbreak; - } - vmcase(OP_BNOT) { - TValue *rb = vRB(i); - lua_Integer ib; - if (tointegerns(rb, &ib)) { - setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib)); - } - else - Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); - vmbreak; - } - vmcase(OP_NOT) { - TValue *rb = vRB(i); - if (l_isfalse(rb)) - setbtvalue(s2v(ra)); - else - setbfvalue(s2v(ra)); - vmbreak; - } - vmcase(OP_LEN) { - Protect(luaV_objlen(L, ra, vRB(i))); - vmbreak; - } - vmcase(OP_CONCAT) { - int n = GETARG_B(i); /* number of elements to concatenate */ - L->top = ra + n; /* mark the end of concat operands */ - ProtectNT(luaV_concat(L, n)); - checkGC(L, L->top); /* 'luaV_concat' ensures correct top */ - vmbreak; - } - vmcase(OP_CLOSE) { - Protect(luaF_close(L, ra, LUA_OK, 1)); - vmbreak; - } - vmcase(OP_TBC) { - /* create new to-be-closed upvalue */ - halfProtect(luaF_newtbcupval(L, ra)); - vmbreak; - } - vmcase(OP_JMP) { - dojump(ci, i, 0); - vmbreak; - } - vmcase(OP_EQ) { - int cond; - TValue *rb = vRB(i); - Protect(cond = luaV_equalobj(L, s2v(ra), rb)); - docondjump(); - vmbreak; - } - vmcase(OP_LT) { - op_order(L, l_lti, LTnum, lessthanothers); - vmbreak; - } - vmcase(OP_LE) { - op_order(L, l_lei, LEnum, lessequalothers); - vmbreak; - } - vmcase(OP_EQK) { - TValue *rb = KB(i); - /* basic types do not use '__eq'; we can use raw equality */ - int cond = luaV_rawequalobj(s2v(ra), rb); - docondjump(); - vmbreak; - } - vmcase(OP_EQI) { - int cond; - int im = GETARG_sB(i); - if (ttisinteger(s2v(ra))) - cond = (ivalue(s2v(ra)) == im); - else if (ttisfloat(s2v(ra))) - cond = luai_numeq(fltvalue(s2v(ra)), cast_num(im)); - else - cond = 0; /* other types cannot be equal to a number */ - docondjump(); - vmbreak; - } - vmcase(OP_LTI) { - op_orderI(L, l_lti, luai_numlt, 0, TM_LT); - vmbreak; - } - vmcase(OP_LEI) { - op_orderI(L, l_lei, luai_numle, 0, TM_LE); - vmbreak; - } - vmcase(OP_GTI) { - op_orderI(L, l_gti, luai_numgt, 1, TM_LT); - vmbreak; - } - vmcase(OP_GEI) { - op_orderI(L, l_gei, luai_numge, 1, TM_LE); - vmbreak; - } - vmcase(OP_TEST) { - int cond = !l_isfalse(s2v(ra)); - docondjump(); - vmbreak; - } - vmcase(OP_TESTSET) { - TValue *rb = vRB(i); - if (l_isfalse(rb) == GETARG_k(i)) - pc++; - else { - setobj2s(L, ra, rb); - donextjump(ci); - } - vmbreak; - } - vmcase(OP_CALL) { - CallInfo *newci; - int b = GETARG_B(i); - int nresults = GETARG_C(i) - 1; - if (b != 0) /* fixed number of arguments? */ - L->top = ra + b; /* top signals number of arguments */ - /* else previous instruction set top */ - savepc(L); /* in case of errors */ - if ((newci = luaD_precall(L, ra, nresults)) == NULL) - updatetrap(ci); /* C call; nothing else to be done */ - else { /* Lua call: run function in this same C frame */ - ci = newci; - ci->callstatus = 0; /* call re-uses 'luaV_execute' */ - goto startfunc; - } - vmbreak; - } - vmcase(OP_TAILCALL) { - int b = GETARG_B(i); /* number of arguments + 1 (function) */ - int nparams1 = GETARG_C(i); - /* delta is virtual 'func' - real 'func' (vararg functions) */ - int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; - if (b != 0) - L->top = ra + b; - else /* previous instruction set top */ - b = cast_int(L->top - ra); - savepc(ci); /* several calls here can raise errors */ - if (TESTARG_k(i)) { - luaF_closeupval(L, base); /* close upvalues from current call */ - lua_assert(L->tbclist < base); /* no pending tbc variables */ - lua_assert(base == ci->func + 1); - } - while (!ttisfunction(s2v(ra))) { /* not a function? */ - luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ - b++; /* there is now one extra argument */ - checkstackGCp(L, 1, ra); - } - if (!ttisLclosure(s2v(ra))) { /* C function? */ - luaD_precall(L, ra, LUA_MULTRET); /* call it */ - updatetrap(ci); - updatestack(ci); /* stack may have been relocated */ - ci->func -= delta; /* restore 'func' (if vararg) */ - luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ - updatetrap(ci); /* 'luaD_poscall' can change hooks */ - goto ret; /* caller returns after the tail call */ - } - ci->func -= delta; /* restore 'func' (if vararg) */ - luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ - goto startfunc; /* execute the callee */ - } - vmcase(OP_RETURN) { - int n = GETARG_B(i) - 1; /* number of results */ - int nparams1 = GETARG_C(i); - if (n < 0) /* not fixed? */ - n = cast_int(L->top - ra); /* get what is available */ - savepc(ci); - if (TESTARG_k(i)) { /* may there be open upvalues? */ - if (L->top < ci->top) - L->top = ci->top; - luaF_close(L, base, CLOSEKTOP, 1); - updatetrap(ci); - updatestack(ci); - } - if (nparams1) /* vararg function? */ - ci->func -= ci->u.l.nextraargs + nparams1; - L->top = ra + n; /* set call for 'luaD_poscall' */ - luaD_poscall(L, ci, n); - updatetrap(ci); /* 'luaD_poscall' can change hooks */ - goto ret; - } - vmcase(OP_RETURN0) { - if (l_unlikely(L->hookmask)) { - L->top = ra; - savepc(ci); - luaD_poscall(L, ci, 0); /* no hurry... */ - trap = 1; - } - else { /* do the 'poscall' here */ - int nres; - L->ci = ci->previous; /* back to caller */ - L->top = base - 1; - for (nres = ci->nresults; l_unlikely(nres > 0); nres--) - setnilvalue(s2v(L->top++)); /* all results are nil */ - } - goto ret; - } - vmcase(OP_RETURN1) { - if (l_unlikely(L->hookmask)) { - L->top = ra + 1; - savepc(ci); - luaD_poscall(L, ci, 1); /* no hurry... */ - trap = 1; - } - else { /* do the 'poscall' here */ - int nres = ci->nresults; - L->ci = ci->previous; /* back to caller */ - if (nres == 0) - L->top = base - 1; /* asked for no results */ - else { - setobjs2s(L, base - 1, ra); /* at least this result */ - L->top = base; - for (; l_unlikely(nres > 1); nres--) - setnilvalue(s2v(L->top++)); /* complete missing results */ - } - } - ret: /* return from a Lua function */ - if (ci->callstatus & CIST_FRESH) - return; /* end this frame */ - else { - ci = ci->previous; - goto returning; /* continue running caller in this frame */ - } - } - vmcase(OP_FORLOOP) { - if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ - lua_Unsigned count = l_castS2U(ivalue(s2v(ra + 1))); - if (count > 0) { /* still more iterations? */ - lua_Integer step = ivalue(s2v(ra + 2)); - lua_Integer idx = ivalue(s2v(ra)); /* internal index */ - chgivalue(s2v(ra + 1), count - 1); /* update counter */ - idx = intop(+, idx, step); /* add step to index */ - chgivalue(s2v(ra), idx); /* update internal index */ - setivalue(s2v(ra + 3), idx); /* and control variable */ - pc -= GETARG_Bx(i); /* jump back */ - } - } - else if (floatforloop(ra)) /* float loop */ - pc -= GETARG_Bx(i); /* jump back */ - updatetrap(ci); /* allows a signal to break the loop */ - vmbreak; - } - vmcase(OP_FORPREP) { - savestate(L, ci); /* in case of errors */ - if (forprep(L, ra)) - pc += GETARG_Bx(i) + 1; /* skip the loop */ - vmbreak; - } - vmcase(OP_TFORPREP) { - /* create to-be-closed upvalue (if needed) */ - halfProtect(luaF_newtbcupval(L, ra + 3)); - pc += GETARG_Bx(i); - i = *(pc++); /* go to next instruction */ - lua_assert(GET_OPCODE(i) == OP_TFORCALL && ra == RA(i)); - goto l_tforcall; - } - vmcase(OP_TFORCALL) { - l_tforcall: - /* 'ra' has the iterator function, 'ra + 1' has the state, - 'ra + 2' has the control variable, and 'ra + 3' has the - to-be-closed variable. The call will use the stack after - these values (starting at 'ra + 4') - */ - /* push function, state, and control variable */ - memcpy(ra + 4, ra, 3 * sizeof(*ra)); - L->top = ra + 4 + 3; - ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */ - updatestack(ci); /* stack may have changed */ - i = *(pc++); /* go to next instruction */ - lua_assert(GET_OPCODE(i) == OP_TFORLOOP && ra == RA(i)); - goto l_tforloop; - } - vmcase(OP_TFORLOOP) { - l_tforloop: - if (!ttisnil(s2v(ra + 4))) { /* continue loop? */ - setobjs2s(L, ra + 2, ra + 4); /* save control variable */ - pc -= GETARG_Bx(i); /* jump back */ - } - vmbreak; - } - vmcase(OP_SETLIST) { - int n = GETARG_B(i); - unsigned int last = GETARG_C(i); - Table *h = hvalue(s2v(ra)); - if (n == 0) - n = cast_int(L->top - ra) - 1; /* get up to the top */ - else - L->top = ci->top; /* correct top in case of emergency GC */ - last += n; - if (TESTARG_k(i)) { - last += GETARG_Ax(*pc) * (MAXARG_C + 1); - pc++; - } - if (last > luaH_realasize(h)) /* needs more space? */ - luaH_resizearray(L, h, last); /* preallocate it at once */ - for (; n > 0; n--) { - TValue *val = s2v(ra + n); - setobj2t(L, &h->array[last - 1], val); - last--; - luaC_barrierback(L, obj2gco(h), val); - } - vmbreak; - } - vmcase(OP_CLOSURE) { - Proto *p = cl->p->p[GETARG_Bx(i)]; - halfProtect(pushclosure(L, p, cl->upvals, base, ra)); - checkGC(L, ra + 1); - vmbreak; - } - vmcase(OP_VARARG) { - int n = GETARG_C(i) - 1; /* required results */ - Protect(luaT_getvarargs(L, ci, ra, n)); - vmbreak; - } - vmcase(OP_VARARGPREP) { - ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p)); - if (l_unlikely(trap)) { /* previous "Protect" updated trap */ - luaD_hookcall(L, ci); - L->oldpc = 1; /* next opcode will be seen as a "new" line */ - } - updatebase(ci); /* function has new base after adjustment */ - vmbreak; - } - vmcase(OP_EXTRAARG) { - lua_assert(0); - vmbreak; - } - } - } -} - -/* }================================================================== */ diff --git a/source/external/lua/lvm.h b/source/external/lua/lvm.h index 1bc16f3..be7b9cb 100644 --- a/source/external/lua/lvm.h +++ b/source/external/lua/lvm.h @@ -43,7 +43,7 @@ typedef enum { F2Ieq, /* no rounding; accepts only integral values */ F2Ifloor, /* takes the floor of the number */ - F2Iceil /* takes the ceil of the number */ + F2Iceil /* takes the ceiling of the number */ } F2Imod; @@ -76,40 +76,40 @@ typedef enum { /* -** fast track for 'gettable': if 't' is a table and 't[k]' is present, -** return 1 with 'slot' pointing to 't[k]' (position of final result). -** Otherwise, return 0 (meaning it will have to check metamethod) -** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL -** (otherwise). 'f' is the raw get function to use. +** fast track for 'gettable' */ -#define luaV_fastget(L,t,k,slot,f) \ - (!ttistable(t) \ - ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ - : (slot = f(hvalue(t), k), /* else, do raw access */ \ - !isempty(slot))) /* result not empty? */ +#define luaV_fastget(t,k,res,f, tag) \ + (tag = (!ttistable(t) ? LUA_VNOTABLE : f(hvalue(t), k, res))) /* ** Special case of 'luaV_fastget' for integers, inlining the fast case ** of 'luaH_getint'. */ -#define luaV_fastgeti(L,t,k,slot) \ - (!ttistable(t) \ - ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ - : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ - ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ - !isempty(slot))) /* result not empty? */ +#define luaV_fastgeti(t,k,res,tag) \ + if (!ttistable(t)) tag = LUA_VNOTABLE; \ + else { luaH_fastgeti(hvalue(t), k, res, tag); } + + +#define luaV_fastset(t,k,val,hres,f) \ + (hres = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val))) + +#define luaV_fastseti(t,k,val,hres) \ + if (!ttistable(t)) hres = HNOTATABLE; \ + else { luaH_fastseti(hvalue(t), k, val, hres); } /* -** Finish a fast set operation (when fast get succeeds). In that case, -** 'slot' points to the place to put the value. +** Finish a fast set operation (when fast set succeeds). */ -#define luaV_finishfastset(L,t,slot,v) \ - { setobj2t(L, cast(TValue *,slot), v); \ - luaC_barrierback(L, gcvalue(t), v); } +#define luaV_finishfastset(L,t,v) luaC_barrierback(L, gcvalue(t), v) +/* +** Shift right is the same as shift left with a negative 'y' +*/ +#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) + LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); @@ -120,10 +120,10 @@ LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, F2Imod mode); LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); -LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, - StkId val, const TValue *slot); +LUAI_FUNC lu_byte luaV_finishget (lua_State *L, const TValue *t, TValue *key, + StkId val, lu_byte tag); LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, - TValue *val, const TValue *slot); + TValue *val, int aux); LUAI_FUNC void luaV_finishOp (lua_State *L); LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); LUAI_FUNC void luaV_concat (lua_State *L, int total); diff --git a/source/external/lua/lzio.c b/source/external/lua/lzio.c deleted file mode 100644 index cd0a02d..0000000 --- a/source/external/lua/lzio.c +++ /dev/null @@ -1,68 +0,0 @@ -/* -** $Id: lzio.c $ -** Buffered streams -** See Copyright Notice in lua.h -*/ - -#define lzio_c -#define LUA_CORE - -#include "lprefix.h" - - -#include - -#include "lua.h" - -#include "llimits.h" -#include "lmem.h" -#include "lstate.h" -#include "lzio.h" - - -int luaZ_fill (ZIO *z) { - size_t size; - lua_State *L = z->L; - const char *buff; - lua_unlock(L); - buff = z->reader(L, z->data, &size); - lua_lock(L); - if (buff == NULL || size == 0) - return EOZ; - z->n = size - 1; /* discount char being returned */ - z->p = buff; - return cast_uchar(*(z->p++)); -} - - -void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { - z->L = L; - z->reader = reader; - z->data = data; - z->n = 0; - z->p = NULL; -} - - -/* --------------------------------------------------------------- read --- */ -size_t luaZ_read (ZIO *z, void *b, size_t n) { - while (n) { - size_t m; - if (z->n == 0) { /* no bytes in buffer? */ - if (luaZ_fill(z) == EOZ) /* try to read more */ - return n; /* no more input; return number of missing bytes */ - else { - z->n++; /* luaZ_fill consumed first byte; put it back */ - z->p--; - } - } - m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ - memcpy(b, z->p, m); - z->n -= m; - z->p += m; - b = (char *)b + m; - n -= m; - } - return 0; -} - diff --git a/source/external/lua/lzio.h b/source/external/lua/lzio.h index 38f397f..49047c9 100644 --- a/source/external/lua/lzio.h +++ b/source/external/lua/lzio.h @@ -32,7 +32,7 @@ typedef struct Mbuffer { #define luaZ_sizebuffer(buff) ((buff)->buffsize) #define luaZ_bufflen(buff) ((buff)->n) -#define luaZ_buffremove(buff,i) ((buff)->n -= (i)) +#define luaZ_buffremove(buff,i) ((buff)->n -= cast_sizet(i)) #define luaZ_resetbuffer(buff) ((buff)->n = 0) @@ -48,6 +48,7 @@ LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data); LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ +LUAI_FUNC const void *luaZ_getaddr (ZIO* z, size_t n); /* --------- Private Part ------------------ */ diff --git a/source/mini/audio/jail_audio.cpp b/source/mini/audio/jail_audio.cpp index 2dca44f..7a60fb8 100644 --- a/source/mini/audio/jail_audio.cpp +++ b/source/mini/audio/jail_audio.cpp @@ -86,7 +86,7 @@ namespace jail static void updateMusic() { if (!music::enabled) return; - if (music::current < 0 || music::current > music::musics.size()) return; + if (music::current < 0 || music::current > static_cast(music::musics.size())) return; auto &m = music::musics[music::current]; if (m.state != music::state::playing) return; @@ -105,7 +105,7 @@ namespace jail if (m.times != 0) { - if (SDL_GetAudioStreamAvailable(m.stream) < int(m.length/2)) { + if (SDL_GetAudioStreamAvailable(m.stream) < static_cast(m.length/2)) { SDL_PutAudioStreamData(m.stream, m.buffer, m.length); } if (m.times>0) m.times--; @@ -120,14 +120,14 @@ namespace jail { if (sound::enabled) { - for (int i=0; i < sound::channel::channels.size(); ++i) { + for (int i=0; i < static_cast(sound::channel::channels.size()); ++i) { auto &c = sound::channel::channels[i]; if (c.state == sound::channel::state::playing) { if (c.times != 0) { auto &s = sound::sounds[c.sound]; - if (SDL_GetAudioStreamAvailable(c.stream) < int(s.length/2)) + if (SDL_GetAudioStreamAvailable(c.stream) < static_cast(s.length/2)) SDL_PutAudioStreamData(c.stream, s.buffer, s.length); if (c.times>0) c.times--; } @@ -169,13 +169,13 @@ namespace jail { if (timerID) SDL_RemoveTimer(timerID); - for (int i=0; i(music::musics.size());++i) music::destroy(i); music::musics.clear(); - for (int i=0; i(sound::channel::channels.size());++i) sound::channel::stop(i); sound::channel::channels.clear(); - for (int i=0; i(sound::sounds.size());++i) sound::destroy(i); sound::sounds.clear(); if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice); @@ -194,8 +194,8 @@ namespace jail int load(const uint8_t* buffer, uint32_t length) { int music = 0; - while (music < musics.size() && musics[music].state != state::invalid) { music++; } - if (music == musics.size()) musics.emplace_back(); + while (music < static_cast(musics.size()) && musics[music].state != state::invalid) { music++; } + if (music == static_cast(musics.size())) musics.emplace_back(); auto &m = musics[music]; @@ -223,7 +223,7 @@ namespace jail long fsize = ftell(f); fseek(f, 0, SEEK_SET); Uint8 *buffer = (Uint8*)malloc(fsize + 1); - if (fread(buffer, fsize, 1, f)!=1) return NULL; + if (fread(buffer, fsize, 1, f)!=1) return -1; fclose(f); int music = load(buffer, fsize); @@ -237,7 +237,7 @@ namespace jail { if (!music::enabled) return; stop(); - if (mus < 0 || mus >= musics.size()) { + if (mus < 0 || mus >= static_cast(musics.size())) { log_msg(LOG_FAIL, "music::play: Illegal music handle: %i\n", mus); return; } @@ -257,7 +257,7 @@ namespace jail void pause() { if (!music::enabled) return; - if (current<0 || current>musics.size()) { + if (current<0 || current>static_cast(musics.size())) { log_msg(LOG_FAIL, "music::pause: Illegal music handle: %i\n", current); return; } @@ -275,7 +275,7 @@ namespace jail void resume() { if (!music::enabled) return; - if (current<0 || current>musics.size()) { + if (current<0 || current>static_cast(musics.size())) { log_msg(LOG_FAIL, "music::resume: Illegal music handle: %i\n", current); return; } @@ -293,7 +293,7 @@ namespace jail void stop() { if (!music::enabled) return; - if (current<0 || current>musics.size()) { + if (current<0 || current>static_cast(musics.size())) { log_msg(LOG_FAIL, "music::stop: Illegal music handle: %i\n", current); return; } @@ -313,7 +313,7 @@ namespace jail void fadeOut(int milliseconds) { if (!music::enabled) return; - if (current<0 || current>musics.size()) { + if (current<0 || current>static_cast(musics.size())) { log_msg(LOG_FAIL, "music::fadeOut: Illegal music handle: %i\n", current); return; } @@ -332,14 +332,14 @@ namespace jail music::state getState() { if (!music::enabled) return music::state::disabled; - if (current<0 || current>musics.size()) return state::invalid; + if (current<0 || current>static_cast(musics.size())) return state::invalid; return musics[current].state; } void destroy(int mus) { if (current == mus) current = -1; - if (mus<0 || mus>musics.size()) { + if (mus<0 || mus>static_cast(musics.size())) { log_msg(LOG_FAIL, "music::destroy: Illegal music handle: %i\n", mus); return; } @@ -355,7 +355,7 @@ namespace jail { volume = SDL_clamp( vol, 0.0f, 1.0f ); - if (current<0 || current>musics.size()) return vol; + if (current<0 || current>static_cast(musics.size())) return vol; auto &m = musics[current]; if (m.state == state::invalid) return vol; @@ -366,7 +366,7 @@ namespace jail void setPosition(float value) { if (!music::enabled) return; - if (current<0 || current>musics.size()) { + if (current<0 || current>static_cast(musics.size())) { log_msg(LOG_FAIL, "music::setPosition: Illegal music handle: %i\n", current); return; } @@ -382,7 +382,7 @@ namespace jail float getPosition() { if (!music::enabled) return 0; - if (current<0 || current>musics.size()) { + if (current<0 || current>static_cast(musics.size())) { log_msg(LOG_FAIL, "music::getPosition: Illegal music handle: %i\n", current); return 0; } @@ -397,7 +397,7 @@ namespace jail void enable(bool value) { - if (!value && music::enabled && current>=0 && current=0 && current(musics.size()) && musics[current].state==state::playing) stop(); music::enabled = value; } @@ -413,8 +413,8 @@ namespace jail int create(uint8_t* buffer, uint32_t length) { int snd = 0; - while (snd < sounds.size() && sounds[snd].buffer) { snd++; } - if (snd == sounds.size()) sounds.emplace_back(); + while (snd < static_cast(sounds.size()) && sounds[snd].buffer) { snd++; } + if (snd == static_cast(sounds.size())) sounds.emplace_back(); auto &s = sounds[snd]; s.buffer = buffer; @@ -425,8 +425,8 @@ namespace jail int load(uint8_t* buffer, uint32_t size) { int snd = 0; - while (snd < sounds.size() && sounds[snd].buffer) { snd++; } - if (snd == sounds.size()) sounds.emplace_back(); + while (snd < static_cast(sounds.size()) && sounds[snd].buffer) { snd++; } + if (snd == static_cast(sounds.size())) sounds.emplace_back(); auto &s = sounds[snd]; SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size),1, &s.spec, &s.buffer, &s.length); @@ -437,8 +437,8 @@ namespace jail int load(const char* filename) { int snd = 0; - while (snd < sounds.size() && sounds[snd].buffer) { snd++; } - if (snd == sounds.size()) sounds.emplace_back(); + while (snd < static_cast(sounds.size()) && sounds[snd].buffer) { snd++; } + if (snd == static_cast(sounds.size())) sounds.emplace_back(); auto &s = sounds[snd]; SDL_LoadWAV(filename, &s.spec, &s.buffer, &s.length); @@ -450,7 +450,7 @@ namespace jail { if (!sound::enabled) return -1; - if (snd<0 || snd>sounds.size()) { + if (snd<0 || snd>static_cast(sounds.size())) { log_msg(LOG_FAIL, "sound::play: Illegal sound handle: %i\n", snd); return -1; } @@ -461,8 +461,8 @@ namespace jail } int chan = 0; - while (chan < channel::channels.size() && channel::channels[chan].state != channel::state::free) { chan++; } - if (chan == channel::channels.size()) channel::channels.emplace_back(); + while (chan < static_cast(channel::channels.size()) && channel::channels[chan].state != channel::state::free) { chan++; } + if (chan == static_cast(channel::channels.size())) channel::channels.emplace_back(); channel::stop(chan); auto &c = channel::channels[chan]; c.sound = snd; @@ -481,7 +481,7 @@ namespace jail { if (!sound::enabled) return -1; - if (snd<0 || snd>sounds.size()) { + if (snd<0 || snd>static_cast(sounds.size())) { log_msg(LOG_FAIL, "sound::playOnChannel: Illegal sound handle: %i\n", snd); return -1; } @@ -491,7 +491,7 @@ namespace jail return -1; } - if (chan<0 || chan>channel::channels.size()) { + if (chan<0 || chan>static_cast(channel::channels.size())) { log_msg(LOG_FAIL, "sound::playOnChannel: Illegal channel handle: %i\n", chan); return -1; } @@ -513,11 +513,11 @@ namespace jail void destroy(int snd) { - for (int i = 0; i < channel::channels.size(); i++) { + for (int i = 0; i < static_cast(channel::channels.size()); i++) { if (channel::channels[i].sound == snd) channel::stop(i); } - if (snd<0 || snd>sounds.size()) { + if (snd<0 || snd>static_cast(sounds.size())) { log_msg(LOG_FAIL, "sound::destroy: Illegal sound handle: %i\n", snd); return; } @@ -529,7 +529,7 @@ namespace jail { volume = SDL_clamp( vol, 0.0f, 1.0f ); - for (int i = 0; i < channel::channels.size(); i++) { + for (int i = 0; i < static_cast(channel::channels.size()); i++) { auto &c = channel::channels[i]; if ( (c.state == channel::state::playing) || (c.state == channel::state::paused) ) SDL_SetAudioStreamGain(c.stream, volume); @@ -540,7 +540,7 @@ namespace jail void enable(bool value) { if (!value && sound::enabled) { - for (int i = 0; i < channel::channels.size(); i++) { + for (int i = 0; i < static_cast(channel::channels.size()); i++) { if (channel::channels[i].state == channel::state::playing) channel::stop(i); } } @@ -560,7 +560,7 @@ namespace jail if (chan == -1) { - for (int i = 0; i < channels.size(); i++) + for (int i = 0; i < static_cast(channels.size()); i++) if (channels[i].state == state::playing) { channels[i].state = state::paused; @@ -568,7 +568,7 @@ namespace jail SDL_UnbindAudioStream(channels[i].stream); } } - else if (chan >= 0 && chan < channels.size()) + else if (chan >= 0 && chan < static_cast(channels.size())) { if (channels[chan].state == state::playing) { @@ -585,7 +585,7 @@ namespace jail if (chan == -1) { - for (int i = 0; i < channels.size(); i++) + for (int i = 0; i < static_cast(channels.size()); i++) if (channels[i].state == state::paused) { channels[i].state = state::playing; @@ -593,7 +593,7 @@ namespace jail SDL_BindAudioStream(sdlAudioDevice, channels[i].stream); } } - else if (chan >= 0 && chan < channels.size()) + else if (chan >= 0 && chan < static_cast(channels.size())) { if (channels[chan].state == state::paused) { @@ -610,7 +610,7 @@ namespace jail if (chan == -1) { - for (int i = 0; i < channels.size(); i++) { + for (int i = 0; i < static_cast(channels.size()); i++) { if (channels[i].state != state::free) SDL_DestroyAudioStream(channels[i].stream); channels[i].stream = nullptr; channels[i].state = state::free; @@ -618,7 +618,7 @@ namespace jail channels[i].sound = -1; } } - else if (chan >= 0 && chan < channels.size()) + else if (chan >= 0 && chan < static_cast(channels.size())) { if (channels[chan].state != state::free) SDL_DestroyAudioStream(channels[chan].stream); channels[chan].stream = nullptr; @@ -631,7 +631,7 @@ namespace jail channel::state getState(int chan) { if (!sound::enabled) return state::disabled; - if (chan < 0 || chan >= channels.size()) return state::invalid; + if (chan < 0 || chan >= static_cast(channels.size())) return state::invalid; return channels[chan].state; } } diff --git a/source/mini/lua/lua.debug.cpp b/source/mini/lua/lua.debug.cpp index c84c9b3..0b3bfec 100644 --- a/source/mini/lua/lua.debug.cpp +++ b/source/mini/lua/lua.debug.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace mini { diff --git a/source/mini/shader/shader.cpp b/source/mini/shader/shader.cpp index 22c119a..1af8772 100644 --- a/source/mini/shader/shader.cpp +++ b/source/mini/shader/shader.cpp @@ -87,12 +87,12 @@ namespace mini void init(const char* vshader, const char* fshader) { - int filesize; - char *vshaderfile = file::getfilebuffer(vshader, filesize, true); - - char *fshaderfile = nullptr; - if (fshader) { fshaderfile = file::getfilebuffer(fshader, filesize, true); } // [TODO] + //int filesize; + //char *vshaderfile = file::getfilebuffer(vshader, filesize, true); + // + //char *fshaderfile = nullptr; + //if (fshader) { fshaderfile = file::getfilebuffer(fshader, filesize, true); } //init(win::state.window, win::state.tex_shader, vshaderfile, fshaderfile); } diff --git a/source/mini/version.h b/source/mini/version.h index fd32257..1f79e0b 100644 --- a/source/mini/version.h +++ b/source/mini/version.h @@ -1,3 +1,3 @@ #pragma once -#define MINI_VERSION "1.5.2" +#define MINI_VERSION "1.5.3"