From 827c3736f357e09168fc108e8e740c6425d37d9b Mon Sep 17 00:00:00 2001 From: Li Jin Date: Tue, 2 Nov 2021 11:17:58 +0800 Subject: fix a wrong code generating issue, update builtin Lua. --- src/3rdParty/lua/lapi.c | 12 +++-- src/3rdParty/lua/lauxlib.h | 8 +++ src/3rdParty/lua/lbaselib.c | 3 +- src/3rdParty/lua/ldebug.c | 2 +- src/3rdParty/lua/ldo.c | 77 ++++++++++++++-------------- src/3rdParty/lua/ldo.h | 17 ++----- src/3rdParty/lua/llimits.h | 14 ++++++ src/3rdParty/lua/lobject.h | 2 +- src/3rdParty/lua/lstrlib.c | 112 +++++++++++++++++++++++++++++++---------- src/3rdParty/lua/ltable.c | 18 +++---- src/3rdParty/lua/ltablib.c | 3 +- src/3rdParty/lua/lua.c | 37 ++++++++------ src/3rdParty/lua/lutf8lib.c | 11 ++-- src/3rdParty/lua/lvm.c | 36 +++++++++---- src/yuescript/yue_compiler.cpp | 3 +- 15 files changed, 224 insertions(+), 131 deletions(-) (limited to 'src') diff --git a/src/3rdParty/lua/lapi.c b/src/3rdParty/lua/lapi.c index 3467891..071a06f 100644 --- a/src/3rdParty/lua/lapi.c +++ b/src/3rdParty/lua/lapi.c @@ -86,10 +86,12 @@ static TValue *index2value (lua_State *L, int idx) { } } + + /* ** Convert a valid actual index (not a pseudo-index) to its address. */ -static StkId index2stack (lua_State *L, int idx) { +l_sinline StkId index2stack (lua_State *L, int idx) { CallInfo *ci = L->ci; if (idx > 0) { StkId o = ci->func + idx; @@ -226,7 +228,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) { ** 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) { +l_sinline void reverse (lua_State *L, StkId from, StkId to) { for (; from < to; from++, to--) { TValue temp; setobj(L, &temp, s2v(from)); @@ -446,7 +448,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { } -static void *touserdata (const TValue *o) { +l_sinline void *touserdata (const TValue *o) { switch (ttype(o)) { case LUA_TUSERDATA: return getudatamem(uvalue(o)); case LUA_TLIGHTUSERDATA: return pvalue(o); @@ -638,7 +640,7 @@ LUA_API int lua_pushthread (lua_State *L) { */ -static int auxgetstr (lua_State *L, const TValue *t, const char *k) { +l_sinline 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)) { @@ -713,7 +715,7 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { } -static int finishrawget (lua_State *L, const TValue *val) { +l_sinline int finishrawget (lua_State *L, const TValue *val) { if (isempty(val)) /* avoid copying empty items to the stack */ setnilvalue(s2v(L->top)); else diff --git a/src/3rdParty/lua/lauxlib.h b/src/3rdParty/lua/lauxlib.h index 72f70e7..6f9695e 100644 --- a/src/3rdParty/lua/lauxlib.h +++ b/src/3rdParty/lua/lauxlib.h @@ -154,6 +154,14 @@ 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) +/* +** Perform arithmetic operations on lua_Integer values with wrap-around +** semantics, as the Lua core does. +*/ +#define luaL_intop(op,v1,v2) \ + ((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2))) + + /* push the value used to represent failure/error */ #define luaL_pushfail(L) lua_pushnil(L) diff --git a/src/3rdParty/lua/lbaselib.c b/src/3rdParty/lua/lbaselib.c index fd6687e..912c4cc 100644 --- a/src/3rdParty/lua/lbaselib.c +++ b/src/3rdParty/lua/lbaselib.c @@ -285,7 +285,8 @@ static int luaB_pairs (lua_State *L) { ** Traversal function for 'ipairs' */ static int ipairsaux (lua_State *L) { - lua_Integer i = luaL_checkinteger(L, 2) + 1; + lua_Integer i = luaL_checkinteger(L, 2); + i = luaL_intop(+, i, 1); lua_pushinteger(L, i); return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; } diff --git a/src/3rdParty/lua/ldebug.c b/src/3rdParty/lua/ldebug.c index 433a875..dde4669 100644 --- a/src/3rdParty/lua/ldebug.c +++ b/src/3rdParty/lua/ldebug.c @@ -64,7 +64,7 @@ static int getbaseline (const Proto *f, int pc, int *basepc) { } else { int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */ - /* estimate must be a lower bond of the correct base */ + /* estimate must be a lower bound 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) diff --git a/src/3rdParty/lua/ldo.c b/src/3rdParty/lua/ldo.c index 93fcbb1..88b20f9 100644 --- a/src/3rdParty/lua/ldo.c +++ b/src/3rdParty/lua/ldo.c @@ -387,15 +387,17 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) { ** 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) { +StkId luaD_tryfuncTM (lua_State *L, StkId func) { const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); StkId p; + checkstackGCp(L, 1, func); /* space for metamethod */ 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 */ + return func; } @@ -405,7 +407,7 @@ void luaD_tryfuncTM (lua_State *L, StkId func) { ** expressions, multiple results for tail calls/single parameters) ** separated. */ -static void moveresults (lua_State *L, StkId res, int nres, int wanted) { +l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) { StkId firstresult; int i; switch (wanted) { /* handle typical cases separately */ @@ -474,33 +476,36 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { /* -** In a tail call, move function and parameters to previous call frame. -** (This is done only when no more errors can occur before entering the -** new function, to keep debug information always consistent.) +** 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). */ -static void moveparams (lua_State *L, StkId prevf, StkId func) { +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; func + i < L->top; i++) /* move down function and arguments */ - setobjs2s(L, prevf + i, func + i); - L->top = prevf + i; /* correct top */ -} - - -static CallInfo *prepCallInfo (lua_State *L, StkId func, int retdel, - int mask) { - CallInfo *ci; - if (isdelta(retdel)) { /* tail call? */ - ci = L->ci; /* reuse stack frame */ - ci->func -= retdel2delta(retdel); /* correct 'func' */ - ci->callstatus |= mask | CIST_TAIL; - moveparams(L, ci->func, func); - } - else { /* regular call */ - ci = L->ci = next_ci(L); /* new frame */ - ci->func = func; - ci->nresults = retdel; - ci->callstatus = mask; - } + 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 */ +} + + +l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, + int mask, StkId top) { + CallInfo *ci = L->ci = next_ci(L); /* new frame */ + ci->func = func; + ci->nresults = nret; + ci->callstatus = mask; + ci->top = top; return ci; } @@ -512,12 +517,8 @@ static CallInfo *prepCallInfo (lua_State *L, StkId func, int retdel, ** 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. -** For regular calls, 'delta1' is 0. For tail calls, 'delta1' is the -** 'delta' (correction of base for vararg functions) plus 1, so that it -** cannot be zero. Like 'moveparams', this correction can only be done -** when no more errors can occur in the call. */ -CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) { +CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { lua_CFunction f; retry: switch (ttypetag(s2v(func))) { @@ -530,8 +531,8 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) { int n; /* number of returns */ CallInfo *ci; checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ - ci = prepCallInfo(L, func, retdel, CIST_C); - ci->top = L->top + LUA_MINSTACK; + L->ci = ci = prepCallInfo(L, func, nresults, CIST_C, + L->top + LUA_MINSTACK); lua_assert(ci->top <= L->stack_last); if (l_unlikely(L->hookmask & LUA_MASKCALL)) { int narg = cast_int(L->top - func) - 1; @@ -551,17 +552,15 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) { int nfixparams = p->numparams; int fsize = p->maxstacksize; /* frame size */ checkstackGCp(L, fsize, func); - ci = prepCallInfo(L, func, retdel, 0); + L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize); ci->u.l.savedpc = p->code; /* starting point */ - ci->top = func + 1 + fsize; 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 */ + func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ goto retry; /* try again with metamethod */ } } @@ -573,7 +572,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int retdel) { ** 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) { +l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) { CallInfo *ci; L->nCcalls += inc; if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) diff --git a/src/3rdParty/lua/ldo.h b/src/3rdParty/lua/ldo.h index 49fbb49..9fb772f 100644 --- a/src/3rdParty/lua/ldo.h +++ b/src/3rdParty/lua/ldo.h @@ -49,18 +49,6 @@ luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) -/* -** 'luaD_precall' is used for regular calls, when it needs the -** number of results, and in tail calls, when it needs the 'delta' -** (correction of base for vararg functions). The argument 'retdel' -** codes these two options. A number of results is represented by -** itself, while a delta is represented by 'delta2retdel(delta)' -*/ -#define delta2retdel(d) (-(d) + LUA_MULTRET - 1) -#define retdel2delta(d) (-(d) + LUA_MULTRET - 1) -#define isdelta(rd) ((rd) < LUA_MULTRET) - - /* type of protected functions, to be ran by 'runprotected' */ typedef void (*Pfunc) (lua_State *L, void *ud); @@ -70,10 +58,11 @@ LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 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 CallInfo *luaD_precall (lua_State *L, StkId func, int retdel); +LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); +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 StkId 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, ptrdiff_t oldtop, ptrdiff_t ef); diff --git a/src/3rdParty/lua/llimits.h b/src/3rdParty/lua/llimits.h index 025f1c8..6c56ba5 100644 --- a/src/3rdParty/lua/llimits.h +++ b/src/3rdParty/lua/llimits.h @@ -165,6 +165,20 @@ typedef LUAI_UACINT l_uacInt; #endif +/* +** 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 + + /* ** type for virtual-machine instructions; ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) diff --git a/src/3rdParty/lua/lobject.h b/src/3rdParty/lua/lobject.h index a1b4554..0e05b3e 100644 --- a/src/3rdParty/lua/lobject.h +++ b/src/3rdParty/lua/lobject.h @@ -68,7 +68,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 */ diff --git a/src/3rdParty/lua/lstrlib.c b/src/3rdParty/lua/lstrlib.c index 74501f7..0b4fdbb 100644 --- a/src/3rdParty/lua/lstrlib.c +++ b/src/3rdParty/lua/lstrlib.c @@ -1090,13 +1090,31 @@ static int lua_number2strx (lua_State *L, char *buff, int sz, /* valid flags in a format specification */ -#if !defined(L_FMTFLAGS) -#define L_FMTFLAGS "-+ #0" +#if !defined(L_FMTFLAGSF) + +/* valid flags for a, A, e, E, f, F, g, and G conversions */ +#define L_FMTFLAGSF "-+#0 " + +/* valid flags for o, x, and X conversions */ +#define L_FMTFLAGSX "-#0" + +/* valid flags for d and i conversions */ +#define L_FMTFLAGSI "-+0 " + +/* valid flags for u conversions */ +#define L_FMTFLAGSU "-0" + +/* valid flags for c, p, and s conversions */ +#define L_FMTFLAGSC "-" + #endif /* -** maximum size of each format specification (such as "%-099.99d") +** Maximum size of each format specification (such as "%-099.99d"): +** Initial '%', flags (up to 5), width (2), period, precision (2), +** length modifier (8), conversion specifier, and final '\0', plus some +** extra. */ #define MAX_FORMAT 32 @@ -1189,25 +1207,53 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { } -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) */ +static const char *get2digits (const char *s) { + if (isdigit(uchar(*s))) { + s++; + if (isdigit(uchar(*s))) s++; /* (2 digits at most) */ + } + return s; +} + + +/* +** Check whether a conversion specification is valid. When called, +** first character in 'form' must be '%' and last character must +** be a valid conversion specifier. 'flags' are the accepted flags; +** 'precision' signals whether to accept a precision. +*/ +static void checkformat (lua_State *L, const char *form, const char *flags, + int precision) { + const char *spec = form + 1; /* skip '%' */ + spec += strspn(spec, flags); /* skip flags */ + if (*spec != '0') { /* a width cannot start with '0' */ + spec = get2digits(spec); /* skip width */ + if (*spec == '.' && precision) { + spec++; + spec = get2digits(spec); /* skip precision */ + } } - if (isdigit(uchar(*p))) - luaL_error(L, "invalid format (width or precision too long)"); + if (!isalpha(uchar(*spec))) /* did not go to the end? */ + luaL_error(L, "invalid conversion specification: '%s'", form); +} + + +/* +** Get a conversion specification and copy it to 'form'. +** Return the address of its last character. +*/ +static const char *getformat (lua_State *L, const char *strfrmt, + char *form) { + /* spans flags, width, and precision ('0' is included as a flag) */ + size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789."); + len++; /* adds following character (should be the specifier) */ + /* still needs space for '%', '\0', plus a length modifier */ + if (len >= MAX_FORMAT - 10) + luaL_error(L, "invalid format (too long)"); *(form++) = '%'; - memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char)); - form += (p - strfrmt) + 1; - *form = '\0'; - return p; + memcpy(form, strfrmt, len * sizeof(char)); + *(form + len) = '\0'; + return strfrmt + len - 1; } @@ -1230,6 +1276,7 @@ static int str_format (lua_State *L) { size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; + const char *flags; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { @@ -1239,25 +1286,35 @@ static int str_format (lua_State *L) { 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 */ + int maxitem = MAX_ITEM; /* maximum length for the result */ + char *buff = luaL_prepbuffsize(&b, maxitem); /* to put result */ + int nb = 0; /* number of bytes in result */ if (++arg > top) return luaL_argerror(L, arg, "no value"); - strfrmt = scanformat(L, strfrmt, form); + strfrmt = getformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { + checkformat(L, form, L_FMTFLAGSC, 0); nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); break; } case 'd': case 'i': - case 'o': case 'u': case 'x': case 'X': { + flags = L_FMTFLAGSI; + goto intcase; + case 'u': + flags = L_FMTFLAGSU; + goto intcase; + case 'o': case 'x': case 'X': + flags = L_FMTFLAGSX; + intcase: { lua_Integer n = luaL_checkinteger(L, arg); + checkformat(L, form, flags, 1); addlenmod(form, LUA_INTEGER_FRMLEN); nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); break; } case 'a': case 'A': + checkformat(L, form, L_FMTFLAGSF, 1); addlenmod(form, LUA_NUMBER_FRMLEN); nb = lua_number2strx(L, buff, maxitem, form, luaL_checknumber(L, arg)); @@ -1268,12 +1325,14 @@ static int str_format (lua_State *L) { /* FALLTHROUGH */ case 'e': case 'E': case 'g': case 'G': { lua_Number n = luaL_checknumber(L, arg); + checkformat(L, form, L_FMTFLAGSF, 1); addlenmod(form, LUA_NUMBER_FRMLEN); nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); break; } case 'p': { const void *p = lua_topointer(L, arg); + checkformat(L, form, L_FMTFLAGSC, 0); if (p == NULL) { /* avoid calling 'printf' with argument NULL */ p = "(null)"; /* result */ form[strlen(form) - 1] = 's'; /* format it as a string */ @@ -1294,7 +1353,8 @@ static int str_format (lua_State *L) { luaL_addvalue(&b); /* keep entire string */ else { luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); - if (!strchr(form, '.') && l >= 100) { + checkformat(L, form, L_FMTFLAGSC, 1); + if (strchr(form, '.') == NULL && l >= 100) { /* no precision and string is too long to be formatted */ luaL_addvalue(&b); /* keep entire string */ } diff --git a/src/3rdParty/lua/ltable.c b/src/3rdParty/lua/ltable.c index af87836..c82286d 100644 --- a/src/3rdParty/lua/ltable.c +++ b/src/3rdParty/lua/ltable.c @@ -150,22 +150,22 @@ static int l_hashfloat (lua_Number n) { ** 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) { +static Node *mainposition (const Table *t, int ktt, const Value kvl) { switch (withvariant(ktt)) { case LUA_VNUMINT: { - lua_Integer key = ivalueraw(*kvl); + lua_Integer key = ivalueraw(kvl); return hashint(t, key); } case LUA_VNUMFLT: { - lua_Number n = fltvalueraw(*kvl); + lua_Number n = fltvalueraw(kvl); return hashmod(t, l_hashfloat(n)); } case LUA_VSHRSTR: { - TString *ts = tsvalueraw(*kvl); + TString *ts = tsvalueraw(kvl); return hashstr(t, ts); } case LUA_VLNGSTR: { - TString *ts = tsvalueraw(*kvl); + TString *ts = tsvalueraw(kvl); return hashpow2(t, luaS_hashlongstr(ts)); } case LUA_VFALSE: @@ -173,15 +173,15 @@ static Node *mainposition (const Table *t, int ktt, const Value *kvl) { case LUA_VTRUE: return hashboolean(t, 1); case LUA_VLIGHTUSERDATA: { - void *p = pvalueraw(*kvl); + void *p = pvalueraw(kvl); return hashpointer(t, p); } case LUA_VLCF: { - lua_CFunction f = fvalueraw(*kvl); + lua_CFunction f = fvalueraw(kvl); return hashpointer(t, f); } default: { - GCObject *o = gcvalueraw(*kvl); + GCObject *o = gcvalueraw(kvl); return hashpointer(t, o); } } @@ -691,7 +691,7 @@ void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { return; } lua_assert(!isdummy(t)); - othern = mainposition(t, keytt(mp), &keyval(mp)); + 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 */ diff --git a/src/3rdParty/lua/ltablib.c b/src/3rdParty/lua/ltablib.c index dbfe250..868d78f 100644 --- a/src/3rdParty/lua/ltablib.c +++ b/src/3rdParty/lua/ltablib.c @@ -59,8 +59,9 @@ static void checktab (lua_State *L, int arg, int what) { 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 */ + lua_Integer e = aux_getn(L, 1, TAB_RW); + e = luaL_intop(+, e, 1); /* first empty element */ switch (lua_gettop(L)) { case 2: { /* called with only 2 arguments */ pos = e; /* insert new element at the end */ diff --git a/src/3rdParty/lua/lua.c b/src/3rdParty/lua/lua.c index 46b48db..0f19004 100644 --- a/src/3rdParty/lua/lua.c +++ b/src/3rdParty/lua/lua.c @@ -89,14 +89,15 @@ static void print_usage (const char *badoption) { lua_writestringerror( "usage: %s [options] [script [args]]\n" "Available options are:\n" - " -e stat execute string 'stat'\n" - " -i enter interactive mode after executing 'script'\n" - " -l name require library 'name' into global 'name'\n" - " -v show version information\n" - " -E ignore environment variables\n" - " -W turn warnings on\n" - " -- stop handling options\n" - " - stop handling options and execute stdin\n" + " -e stat execute string 'stat'\n" + " -i enter interactive mode after executing 'script'\n" + " -l mod require library 'mod' into global 'mod'\n" + " -l g=mod require library 'mod' into global 'g'\n" + " -v show version information\n" + " -E ignore environment variables\n" + " -W turn warnings on\n" + " -- stop handling options\n" + " - stop handling options and execute stdin\n" , progname); } @@ -207,16 +208,22 @@ static int dostring (lua_State *L, const char *s, const char *name) { /* -** Calls 'require(name)' and stores the result in a global variable -** with the given name. +** Receives 'globname[=modname]' and runs 'globname = require(modname)'. */ -static int dolibrary (lua_State *L, const char *name) { +static int dolibrary (lua_State *L, char *globname) { int status; + char *modname = strchr(globname, '='); + if (modname == NULL) /* no explicit name? */ + modname = globname; /* module name is equal to global name */ + else { + *modname = '\0'; /* global name ends here */ + modname++; /* module name starts after the '=' */ + } lua_getglobal(L, "require"); - lua_pushstring(L, name); - status = docall(L, 1, 1); /* call 'require(name)' */ + lua_pushstring(L, modname); + status = docall(L, 1, 1); /* call 'require(modname)' */ if (status == LUA_OK) - lua_setglobal(L, name); /* global[name] = require return */ + lua_setglobal(L, globname); /* globname = require(modname) */ return report(L, status); } @@ -327,7 +334,7 @@ static int runargs (lua_State *L, char **argv, int n) { switch (option) { case 'e': case 'l': { int status; - const char *extra = argv[i] + 2; /* both options need an argument */ + char *extra = argv[i] + 2; /* both options need an argument */ if (*extra == '\0') extra = argv[++i]; lua_assert(extra != NULL); status = (option == 'e') diff --git a/src/3rdParty/lua/lutf8lib.c b/src/3rdParty/lua/lutf8lib.c index 901d985..e7bf098 100644 --- a/src/3rdParty/lua/lutf8lib.c +++ b/src/3rdParty/lua/lutf8lib.c @@ -224,14 +224,11 @@ static int byteoffset (lua_State *L) { 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 */ + lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2); + if (n < len) { + while (iscont(s + n)) n++; /* skip continuation bytes */ } - if (n >= (lua_Integer)len) + if (n >= len) /* (also handles original 'n' being negative) */ return 0; /* no more codepoints */ else { utfint code; diff --git a/src/3rdParty/lua/lvm.c b/src/3rdParty/lua/lvm.c index c84a665..49ed3dd 100644 --- a/src/3rdParty/lua/lvm.c +++ b/src/3rdParty/lua/lvm.c @@ -406,7 +406,7 @@ static int l_strcmp (const TString *ls, const TString *rs) { ** from float to int.) ** When 'f' is NaN, comparisons must result in false. */ -static int LTintfloat (lua_Integer i, lua_Number f) { +l_sinline 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) */ @@ -423,7 +423,7 @@ static int LTintfloat (lua_Integer i, lua_Number f) { ** 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) { +l_sinline 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) */ @@ -440,7 +440,7 @@ static int LEintfloat (lua_Integer i, lua_Number f) { ** Check whether float 'f' is less than integer 'i'. ** See comments on previous function. */ -static int LTfloatint (lua_Number f, lua_Integer i) { +l_sinline 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 */ @@ -457,7 +457,7 @@ static int LTfloatint (lua_Number f, lua_Integer i) { ** 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) { +l_sinline 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 */ @@ -473,7 +473,7 @@ static int LEfloatint (lua_Number f, lua_Integer i) { /* ** Return 'l < r', for numbers. */ -static int LTnum (const TValue *l, const TValue *r) { +l_sinline int LTnum (const TValue *l, const TValue *r) { lua_assert(ttisnumber(l) && ttisnumber(r)); if (ttisinteger(l)) { lua_Integer li = ivalue(l); @@ -495,7 +495,7 @@ static int LTnum (const TValue *l, const TValue *r) { /* ** Return 'l <= r', for numbers. */ -static int LEnum (const TValue *l, const TValue *r) { +l_sinline int LEnum (const TValue *l, const TValue *r) { lua_assert(ttisnumber(l) && ttisnumber(r)); if (ttisinteger(l)) { lua_Integer li = ivalue(l); @@ -768,6 +768,7 @@ lua_Number luaV_modf (lua_State *L, lua_Number m, lua_Number n) { */ #define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y)) + lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { if (y < 0) { /* shift right? */ if (y <= -NBITS) return 0; @@ -1108,7 +1109,7 @@ void luaV_finishOp (lua_State *L) { #define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) /* -** Protect code that can only raise errors. (That is, it cannnot change +** Protect code that can only raise errors. (That is, it cannot change ** the stack or hooks.) */ #define halfProtect(exp) (savestate(L,ci), (exp)) @@ -1647,19 +1648,32 @@ void luaV_execute (lua_State *L, CallInfo *ci) { int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; if (b != 0) L->top = ra + b; - /* else previous instruction set top */ + 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); } - if (luaD_precall(L, ra, delta2retdel(delta))) /* Lua function? */ - goto startfunc; /* execute the callee */ - else { /* C function */ + while (!ttisfunction(s2v(ra))) { /* not a function? */ + ra = luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ + b++; /* there is now one extra argument */ + } + 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 */ } + else { /* Lua function */ + 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 */ diff --git a/src/yuescript/yue_compiler.cpp b/src/yuescript/yue_compiler.cpp index 415fcd3..e004821 100755 --- a/src/yuescript/yue_compiler.cpp +++ b/src/yuescript/yue_compiler.cpp @@ -60,7 +60,7 @@ using namespace parserlib; typedef std::list str_list; -const std::string_view version = "0.8.4"sv; +const std::string_view version = "0.8.5"sv; const std::string_view extension = "yue"sv; class YueCompilerImpl { @@ -530,6 +530,7 @@ private: } if (!exp) return nullptr; BLOCK_START + BREAK_IF(exp->nilCoalesed); BREAK_IF(!exp->opValues.empty()); BREAK_IF(exp->pipeExprs.size() != 1); auto unary = static_cast(exp->pipeExprs.back()); -- cgit v1.2.3-55-g6feb