diff --git a/lapi.c b/lapi.c index 8bc2ddd1..27fa5247 100644 --- a/lapi.c +++ b/lapi.c @@ -187,7 +187,7 @@ LUA_API void lua_settop (lua_State *L, int idx) { api_check(L, idx <= ci->top.p - (func + 1), "new top too large"); diff = ((func + 1) + idx) - L->top.p; for (; diff > 0; diff--) - setnilvalue2s(L->top.p++); /* clear new slots */ + setnilvalue(s2v(L->top.p++)); /* clear new slots */ } else { api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top"); @@ -210,7 +210,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) { api_check(L, (L->ci->callstatus & CIST_TBC) && (L->tbclist.p == level), "no variable to close at given level"); level = luaF_close(L, level, CLOSEKTOP, 0); - setnilvalue2s(level); + setnilvalue(s2v(level)); lua_unlock(L); } @@ -366,7 +366,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { } -LUA_API unsigned lua_numbertocstring (lua_State *L, int idx, char *buff) { +LUA_API unsigned (lua_numbertocstring) (lua_State *L, int idx, char *buff) { const TValue *o = index2value(L, idx); if (ttisnumber(o)) { unsigned len = luaO_tostringbuff(o, buff); @@ -513,7 +513,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { LUA_API void lua_pushnil (lua_State *L) { lua_lock(L); - setnilvalue2s(L->top.p); + setnilvalue(s2v(L->top.p)); api_incr_top(L); lua_unlock(L); } @@ -570,7 +570,7 @@ LUA_API const char *lua_pushexternalstring (lua_State *L, LUA_API const char *lua_pushstring (lua_State *L, const char *s) { lua_lock(L); if (s == NULL) - setnilvalue2s(L->top.p); + setnilvalue(s2v(L->top.p)); else { TString *ts; ts = luaS_new(L, s); @@ -743,7 +743,7 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { static int finishrawget (lua_State *L, lu_byte tag) { if (tagisempty(tag)) /* avoid copying empty items to the stack */ - setnilvalue2s(L->top.p); + setnilvalue(s2v(L->top.p)); api_incr_top(L); lua_unlock(L); return novariant(tag); @@ -836,7 +836,7 @@ LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) { o = index2value(L, idx); api_check(L, ttisfulluserdata(o), "full userdata expected"); if (n <= 0 || n > uvalue(o)->nuvalue) { - setnilvalue2s(L->top.p); + setnilvalue(s2v(L->top.p)); t = LUA_TNONE; } else { @@ -1122,7 +1122,6 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, ZIO z; TStatus status; lua_lock(L); - luaC_checkGC(L); if (!chunkname) chunkname = "?"; luaZ_init(L, &z, reader, data); status = luaD_protectedparser(L, &z, chunkname, mode); @@ -1202,16 +1201,11 @@ LUA_API int lua_gc (lua_State *L, int what, ...) { case LUA_GCSTEP: { lu_byte oldstp = g->gcstp; l_mem n = cast(l_mem, va_arg(argp, size_t)); - l_mem newdebt; int work = 0; /* true if GC did some work */ g->gcstp = 0; /* allow GC to run (other bits must be zero here) */ if (n <= 0) - newdebt = 0; /* force to run one basic step */ - else if (g->GCdebt >= n - MAX_LMEM) /* no overflow? */ - newdebt = g->GCdebt - n; - else /* overflow */ - newdebt = -MAX_LMEM; /* set debt to mininum value */ - luaE_setdebt(g, newdebt); + n = g->GCdebt; /* force to run one basic step */ + luaE_setdebt(g, g->GCdebt - n); luaC_condGC(L, (void)0, work = 1); if (work && g->gcstate == GCSpause) /* end of cycle? */ res = 1; /* signal it */ @@ -1299,8 +1293,8 @@ LUA_API void lua_toclose (lua_State *L, int idx) { LUA_API void lua_concat (lua_State *L, int n) { lua_lock(L); + api_checknelems(L, n); if (n > 0) { - api_checkpop(L, n); luaV_concat(L, n); luaC_checkGC(L); } @@ -1418,7 +1412,7 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { TValue *fi; lua_lock(L); fi = index2value(L, funcindex); - api_checkpop(L, 1); + api_checknelems(L, 1); name = aux_upvalue(fi, n, &val, &owner); if (name) { L->top.p--; diff --git a/lauxlib.c b/lauxlib.c index 8620c8b3..7cf90cb7 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -513,25 +513,12 @@ static const luaL_Reg boxmt[] = { /* box metamethods */ }; -/* -** Get/create metatable (MT) for boxes -*/ -static void getBoxMT (lua_State *L) { - const char *BOXMT = "_UBOX*"; /* key for the metatable */ - if (luaL_getmetatable(L, BOXMT) == LUA_TNIL) { /* MT not created yet? */ - luaL_newlibtable(L, boxmt); /* create it */ - luaL_setfuncs(L, boxmt, 0); /* initialize it */ - lua_copy(L, -1, -2); /* change stack from nil,MT to MT,MT */ - lua_setfield(L, LUA_REGISTRYINDEX, BOXMT); /* store MT in the registry */ - } -} - - static void newbox (lua_State *L) { UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0); box->box = NULL; box->bsize = 0; - getBoxMT(L); + if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */ + luaL_setfuncs(L, boxmt, 0); /* set its metamethods */ lua_setmetatable(L, -2); } @@ -887,7 +874,7 @@ LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { - return luaL_loadbufferx(L, s, strlen(s), s, "t"); + return luaL_loadbuffer(L, s, strlen(s), s); } /* }====================================================== */ diff --git a/lauxlib.h b/lauxlib.h index 2d015362..7f1d3ca1 100644 --- a/lauxlib.h +++ b/lauxlib.h @@ -81,8 +81,8 @@ 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); +LUALIB_API void *luaL_alloc (void *ud, void *ptr, size_t osize, + size_t nsize); /* predefined references */ @@ -103,7 +103,7 @@ 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 unsigned luaL_makeseed (lua_State *L); LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); diff --git a/lbaselib.c b/lbaselib.c index 3962ea53..891bb90f 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -340,11 +340,9 @@ static int load_aux (lua_State *L, int status, int envidx) { static const char *getMode (lua_State *L, int idx) { - const char *mode = luaL_optstring(L, idx, NULL); - if (mode != NULL && strchr(mode, 'B') != NULL) { - /* Lua code cannot use fixed buffers */ + const char *mode = luaL_optstring(L, idx, "bt"); + if (strchr(mode, 'B') != NULL) /* Lua code cannot use fixed buffers */ luaL_argerror(L, idx, "invalid mode"); - } return mode; } @@ -366,24 +364,33 @@ static int luaB_loadfile (lua_State *L) { /* -** Reader for generic 'load' 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) { - int *firstcall = cast(int *, ud); + (void)(ud); /* not used */ luaL_checkstack(L, 2, "too many nested functions"); - if (*firstcall) - *firstcall = 0; - else - lua_pop(L, 1); /* remove previous result */ 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"); - return lua_tolstring(L, -1, size); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tolstring(L, RESERVEDSLOT, size); } @@ -398,10 +405,10 @@ static int luaB_load (lua_State *L) { status = luaL_loadbufferx(L, s, l, chunkname, mode); } else { /* loading from a reader function */ - int firstcall = 1; /* userdata for generic_reader */ const char *chunkname = luaL_optstring(L, 2, "=(load)"); luaL_checktype(L, 1, LUA_TFUNCTION); - status = lua_load(L, generic_reader, &firstcall, chunkname, mode); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, NULL, chunkname, mode); } return load_aux(L, status, env); } @@ -418,7 +425,7 @@ static int dofilecont (lua_State *L, int d1, lua_KContext d2) { static int luaB_dofile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); lua_settop(L, 1); - if (l_unlikely(luaL_loadfilex(L, fname, "bt") != LUA_OK)) + 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); diff --git a/lcode.c b/lcode.c index 8b61d5de..4caa8046 100644 --- a/lcode.c +++ b/lcode.c @@ -663,11 +663,11 @@ static int boolT (FuncState *fs) { ** Add nil to list of constants and return its index. */ static int nilK (FuncState *fs) { - lua_State *L = fs->ls->L; - TValue k; + TValue k, v; + setnilvalue(&v); /* cannot use nil as key; instead use table itself */ - sethvalue(L, &k, fs->kcache); - return k2proto(fs, &k, &G(L)->nilvalue); + sethvalue(fs->ls->L, &k, fs->kcache); + return k2proto(fs, &k, &v); } @@ -827,7 +827,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { } /* FALLTHROUGH */ case VLOCAL: { /* already in a register */ int temp = e->u.var.ridx; - e->u.info = temp; /* (avoid a direct assignment; values overlap) */ + e->u.info = temp; /* (can't do a direct assignment; values overlap) */ e->k = VNONRELOC; /* becomes a non-relocatable value */ break; } @@ -1365,7 +1365,7 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { luaK_exp2anyreg(fs, t); /* put it in a register */ if (t->k == VUPVAL) { lu_byte temp = cast_byte(t->u.info); /* upvalue index */ - t->u.ind.t = temp; /* (avoid a direct assignment; values overlap) */ + t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */ lua_assert(isKstr(fs, k)); fillidxk(t, k->u.info, VINDEXUP); /* literal short string */ } @@ -1373,13 +1373,12 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { int kreg = luaK_exp2anyreg(fs, k); /* put key in some register */ lu_byte vreg = cast_byte(t->u.var.ridx); /* register with vararg param. */ lua_assert(vreg == fs->f->numparams); - t->u.ind.t = vreg; /* (avoid a direct assignment; values may overlap?) */ + t->u.ind.t = vreg; /* (avoid a direct assignment; values may overlap) */ fillidxk(t, kreg, VVARGIND); /* 't' represents 'vararg[k]' */ } else { /* register index of the table */ - lu_byte temp = cast_byte((t->k == VLOCAL) ? t->u.var.ridx: t->u.info); - t->u.ind.t = temp; /* (avoid a direct assignment; values may overlap?) */ + t->u.ind.t = cast_byte((t->k == VLOCAL) ? t->u.var.ridx: t->u.info); if (isKstr(fs, k)) fillidxk(t, k->u.info, VINDEXSTR); /* literal short string */ else if (isCint(k)) /* int. constant in proper range? */ @@ -1934,6 +1933,8 @@ void luaK_finish (FuncState *fs) { p->flag &= cast_byte(~PF_VAHID); /* then it will not use hidden args. */ for (i = 0; i < fs->pc; i++) { Instruction *pc = &p->code[i]; + /* avoid "not used" warnings when assert is off (for 'onelua.c') */ + (void)luaP_isOT; (void)luaP_isIT; lua_assert(i == 0 || luaP_isOT(*(pc - 1)) == luaP_isIT(*pc)); switch (GET_OPCODE(*pc)) { case OP_RETURN0: case OP_RETURN1: { diff --git a/ldblib.c b/ldblib.c index 051327cc..c7b74812 100644 --- a/ldblib.c +++ b/ldblib.c @@ -427,7 +427,7 @@ static int db_debug (lua_State *L) { if (fgets(buffer, sizeof(buffer), stdin) == NULL || strcmp(buffer, "cont\n") == 0) return 0; - if (luaL_loadbufferx(L, buffer, strlen(buffer), "=(debug command)", "t") || + 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 */ diff --git a/ldebug.c b/ldebug.c index 61c52749..8df5f5f2 100644 --- a/ldebug.c +++ b/ldebug.c @@ -150,7 +150,7 @@ LUA_API lua_Hook lua_gethook (lua_State *L) { LUA_API int lua_gethookmask (lua_State *L) { - return cast_int(L->hookmask); + return L->hookmask; } @@ -291,7 +291,7 @@ static int nextline (const Proto *p, int currentline, int pc) { static void collectvalidlines (lua_State *L, Closure *f) { if (!LuaClosure(f)) { - setnilvalue2s(L->top.p); + setnilvalue(s2v(L->top.p)); api_incr_top(L); } else { @@ -580,7 +580,7 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, kname(p, k, name); return isEnv(p, lastpc, i, 1); } - case OP_GETTABLE: case OP_GETVARG: { + case OP_GETTABLE: { int k = GETARG_C(i); /* key index */ rname(p, lastpc, k, name); return isEnv(p, lastpc, i, 0); diff --git a/ldo.c b/ldo.c index fe8bf20f..6d0184ec 100644 --- a/ldo.c +++ b/ldo.c @@ -221,21 +221,13 @@ l_noret luaD_errerr (lua_State *L) { /* -** Check whether stacks have enough space to run a simple function (such -** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack, two -** available CallInfos, and two "slots" in the C stack. +** Check whether stack has enough space to run a simple function (such +** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack and +** 2 slots in the C stack. */ int luaD_checkminstack (lua_State *L) { - if (getCcalls(L) >= LUAI_MAXCCALLS - 2) - return 0; /* not enough C-stack slots */ - if (L->ci->next == NULL && luaE_extendCI(L, 0) == NULL) - return 0; /* unable to allocate first ci */ - if (L->ci->next->next == NULL && luaE_extendCI(L, 0) == NULL) - return 0; /* unable to allocate second ci */ - if (L->stack_last.p - L->top.p >= BASIC_STACK_SIZE) - return 1; /* enough (BASIC_STACK_SIZE) free slots in the Lua stack */ - else /* try to grow stack to a size with enough free slots */ - return luaD_growstack(L, BASIC_STACK_SIZE, 0); + return ((stacksize(L) < MAXSTACK - BASIC_STACK_SIZE) && + (getCcalls(L) < LUAI_MAXCCALLS - 2)); } @@ -349,7 +341,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { correctstack(L, oldstack); /* change offsets back to pointers */ L->stack_last.p = L->stack.p + newsize; for (i = oldsize + EXTRA_STACK; i < newsize + EXTRA_STACK; i++) - setnilvalue2s(newstack + i); /* erase new segment */ + setnilvalue(s2v(newstack + i)); /* erase new segment */ return 1; } @@ -430,6 +422,12 @@ void luaD_shrinkstack (lua_State *L) { luaE_shrinkCI(L); /* shrink CI list */ } + +void luaD_inctop (lua_State *L) { + L->top.p++; + luaD_checkstack(L, 1); +} + /* }================================================================== */ @@ -548,7 +546,7 @@ l_sinline void genmoveresults (lua_State *L, StkId res, int nres, 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 */ - setnilvalue2s(res + i); + setnilvalue(s2v(res + i)); L->top.p = res + wanted; /* top points after the last result */ } @@ -568,7 +566,7 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, return; case 1 + 1: /* one value needed */ if (nres == 0) /* no results? */ - setnilvalue2s(res); /* adjust with nil */ + setnilvalue(s2v(res)); /* adjust with nil */ else /* at least one result */ setobjs2s(L, res, L->top.p - nres); /* move it to proper place */ L->top.p = res + 1; @@ -618,7 +616,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { -#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L, 1)) +#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) /* @@ -688,7 +686,7 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, setobjs2s(L, ci->func.p + i, func + i); func = ci->func.p; /* moved-down function */ for (; narg1 <= nfixparams; narg1++) - setnilvalue2s(func + narg1); /* complete missing arguments */ + setnilvalue(s2v(func + narg1)); /* complete missing arguments */ ci->top.p = func + 1 + fsize; /* top for new function */ lua_assert(ci->top.p <= L->stack_last.p); ci->u.l.savedpc = p->code; /* starting point */ @@ -735,7 +733,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { L->ci = ci = prepCallInfo(L, func, status, func + 1 + fsize); ci->u.l.savedpc = p->code; /* starting point */ for (; narg < nfixparams; narg++) - setnilvalue2s(L->top.p++); /* complete missing arguments */ + setnilvalue(s2v(L->top.p++)); /* complete missing arguments */ lua_assert(ci->top.p <= L->stack_last.p); return ci; } @@ -1122,54 +1120,28 @@ static void checkmode (lua_State *L, const char *mode, const char *x) { } -/* -** Before the first call to the reader function, Lua reserves a slot -** with a table for anchoring stuff. -*/ static void f_parser (lua_State *L, void *ud) { LClosure *cl; struct SParser *p = cast(struct SParser *, ud); const char *mode = p->mode ? p->mode : "bt"; - int c; - Table *anchor; - ptrdiff_t otop = savestack(L, L->top.p); /* original top */ - luaD_checkstack(L, 2); - anchor = luaH_new(L); /* create the anchor table */ - sethvalue2s(L, L->top.p++, anchor); /* anchor the anchor table */ - c = zgetc(p->z); /* read first character */ + int c = zgetc(p->z); /* read first character */ if (c == LUA_SIGNATURE[0]) { int fixed = 0; if (strchr(mode, 'B') != NULL) fixed = 1; else checkmode(L, mode, "binary"); - cl = luaU_undump(L, p->z, anchor, p->name, fixed); + cl = luaU_undump(L, p->z, p->name, fixed); } else { checkmode(L, mode, "text"); - cl = luaY_parser(L, p->z, anchor, &p->buff, &p->dyd, p->name, c); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); } - L->top.p = restorestack(L, otop); /* restore stack */ - setclLvalue2s(L, L->top.p++, cl); /* push closure */ lua_assert(cl->nupvalues == cl->p->sizeupvalues); luaF_initupvals(L, cl); } -/* -** Anchor an object in a table in the stack. First, anchor the object -** temporarily in the stack, as luaH_set may call an emergency GC. -** Then, add it in the table with itself as its key. -*/ -void luaD_anchorobj (lua_State *L, Table *anchor, GCObject *obj) { - setgcovalue(L, s2v(L->top.p++), obj); /* temporary anchor in the stack */ - luaH_set(L, anchor, s2v(L->top.p - 1), s2v(L->top.p - 1)); - /* Because this is a new key, luaH_set will call the GC barrier, so - we don't need to call the barrier again here */ - L->top.p--; -} - - TStatus luaD_protectedparser (lua_State *L, ZIO *z, const char *name, const char *mode) { struct SParser p; diff --git a/ldo.h b/ldo.h index 85a00e38..b6472954 100644 --- a/ldo.h +++ b/ldo.h @@ -88,8 +88,8 @@ 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 void luaD_anchorobj (lua_State *L, Table *anchor, GCObject *obj); LUAI_FUNC l_noret luaD_throw (lua_State *L, TStatus errcode); LUAI_FUNC l_noret luaD_throwbaselevel (lua_State *L, TStatus errcode); diff --git a/lgc.c b/lgc.c index cf4160c1..c64d74b8 100644 --- a/lgc.c +++ b/lgc.c @@ -709,7 +709,7 @@ static l_mem traversethread (global_State *g, lua_State *th) { if (!g->gcemergency) luaD_shrinkstack(th); /* do not change stack in emergency cycle */ for (o = th->top.p; o < th->stack_last.p + EXTRA_STACK; o++) - setnilvalue2s(o); /* clear dead stack slice */ + 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 */ @@ -1293,7 +1293,7 @@ static void finishgencycle (lua_State *L, global_State *g) { correctgraylists(g); checkSizes(L, g); g->gcstate = GCSpropagate; /* skip restart */ - if (g->tobefnz != NULL && !g->gcemergency && luaD_checkminstack(L)) + if (!g->gcemergency && luaD_checkminstack(L)) callallpendingfinalizers(L); } @@ -1472,8 +1472,7 @@ static int checkmajorminor (lua_State *L, global_State *g) { if (g->gckind == KGC_GENMAJOR) { /* generational mode? */ l_mem numbytes = gettotalbytes(g); l_mem addedbytes = numbytes - g->GCmajorminor; - l_mem limit = (addedbytes < 0) ? 0 - : applygcparam(g, MAJORMINOR, addedbytes); + l_mem limit = applygcparam(g, MAJORMINOR, addedbytes); l_mem tobecollected = numbytes - g->GCmarked; if (tobecollected > limit) { atomic2gen(L, g); /* return to generational mode */ @@ -1673,7 +1672,7 @@ static l_mem singlestep (lua_State *L, int fast) { GCTM(L); /* call one finalizer */ stepresult = CWUFIN; } - else { /* no more finalizers or emergency mode or not enough stack + else { /* no more finalizers or emergency mode or no enough stack to run finalizers */ g->gcstate = GCSpause; /* finish collection */ stepresult = step2pause; diff --git a/lgc.h b/lgc.h index 193ac0fc..ee054179 100644 --- a/lgc.h +++ b/lgc.h @@ -231,9 +231,8 @@ #endif #define luaC_condGC(L,pre,pos) \ - { if (G(L)->GCdebt <= 0) \ - { pre; luaC_step(L); condchangemem(L,{},{},0); pos;} \ - else condchangemem(L,pre,pos,0); } + { 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) diff --git a/llex.c b/llex.c index 7cd9fcaf..f8bb3ea4 100644 --- a/llex.c +++ b/llex.c @@ -188,7 +188,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, so they cannot be collected */ ls->envn = luaS_newliteral(L, LUA_ENV); /* get env string */ ls->brkn = luaS_newliteral(L, "break"); /* get "break" string */ -#if LUA_COMPAT_GLOBAL +#if defined(LUA_COMPAT_GLOBAL) /* compatibility mode: "global" is not a reserved word */ ls->glbn = luaS_newliteral(L, "global"); /* get "global" string */ ls->glbn->extra = 0; /* mark it as not reserved */ diff --git a/llimits.h b/llimits.h index 3f037255..fc5cb276 100644 --- a/llimits.h +++ b/llimits.h @@ -234,12 +234,12 @@ typedef unsigned long l_uint32; /* floor division (defined as 'floor(a/b)') */ #if !defined(luai_numidiv) -#define luai_numidiv(L,a,b) l_floor(luai_numdiv(L,a,b)) +#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) #endif /* float division */ #if !defined(luai_numdiv) -#define luai_numdiv(L,a,b) ((void)L, (a)/(b)) +#define luai_numdiv(L,a,b) ((a)/(b)) #endif /* @@ -267,10 +267,10 @@ typedef unsigned long l_uint32; /* the others are quite standard operations */ #if !defined(luai_numadd) -#define luai_numadd(L,a,b) ((void)L, (a)+(b)) -#define luai_numsub(L,a,b) ((void)L, (a)-(b)) -#define luai_nummul(L,a,b) ((void)L, (a)*(b)) -#define luai_numunm(L,a) ((void)L, -(a)) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numunm(L,a) (-(a)) #define luai_numeq(a,b) ((a)==(b)) #define luai_numlt(a,b) ((a)<(b)) #define luai_numle(a,b) ((a)<=(b)) diff --git a/lmathlib.c b/lmathlib.c index 87e7462a..a6b13f96 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -704,35 +704,35 @@ static int math_log10 (lua_State *L) { 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}, + {"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}, + {"fmod", math_fmod}, {"frexp", math_frexp}, - {"ult", math_ult}, + {"ult", math_ult}, {"ldexp", math_ldexp}, - {"log", math_log}, - {"max", math_max}, - {"min", math_min}, - {"modf", math_modf}, - {"rad", math_rad}, - {"sin", math_sin}, - {"sqrt", math_sqrt}, - {"tan", math_tan}, + {"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}, + {"cosh", math_cosh}, + {"sinh", math_sinh}, + {"tanh", math_tanh}, + {"pow", math_pow}, {"log10", math_log10}, #endif /* placeholders */ diff --git a/loadlib.c b/loadlib.c index ef09c9a5..8d2e68e2 100644 --- a/loadlib.c +++ b/loadlib.c @@ -541,7 +541,7 @@ static int searcher_Lua (lua_State *L) { 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_loadfilex(L, filename, "bt") == LUA_OK), filename); + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); } diff --git a/lobject.c b/lobject.c index 6997cfd0..763b4846 100644 --- a/lobject.c +++ b/lobject.c @@ -89,7 +89,6 @@ lu_byte luaO_codeparam (unsigned int p) { l_mem luaO_applyparam (lu_byte p, l_mem x) { int m = p & 0xF; /* mantissa */ int e = (p >> 4); /* exponent */ - lua_assert(x >= 0); if (e > 0) { /* normalized? */ e--; /* correct exponent */ m += 0x10; /* correct mantissa; maximum value is 0x1F */ diff --git a/lobject.h b/lobject.h index 82bd9703..156c942f 100644 --- a/lobject.h +++ b/lobject.h @@ -208,8 +208,7 @@ typedef union { #define ttisstrictnil(o) checktag((o), LUA_VNIL) -#define setnilvalue(obj) settt_(obj, LUA_VNIL) -#define setnilvalue2s(stk) setnilvalue(s2v(stk)) +#define setnilvalue(obj) settt_(obj, LUA_VNIL) #define isabstkey(v) checktag((v), LUA_VABSTKEY) @@ -827,7 +826,7 @@ typedef struct Table { #define twoto(x) (1u<<(x)) -#define sizenode(t) cast_uint(twoto((t)->lsizenode)) +#define sizenode(t) (twoto((t)->lsizenode)) /* size of buffer for 'luaO_utf8esc' function */ diff --git a/lopcodes.c b/lopcodes.c index bb1a4162..7e182315 100644 --- a/lopcodes.c +++ b/lopcodes.c @@ -104,26 +104,35 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETVARG */ ,opmode(0, 0, 0, 0, 0, iABx) /* OP_ERRNNIL */ - ,opmode(0, 0, 0, 0, 0, iABC) /* OP_VARARGPREP */ + ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ }; -#define testITMode(m) (luaP_opmodes[m] & (1 << 5)) + +/* +** Check whether instruction sets top for next instruction, that is, +** it results in multiple values. +*/ +int luaP_isOT (Instruction i) { + OpCode op = GET_OPCODE(i); + switch (op) { + case OP_TAILCALL: return 1; + default: + return testOTMode(op) && GETARG_C(i) == 0; + } +} /* -** Check whether instruction uses top. That happens for OP_VARARGPREP -** and for instructions that use multiple values set by the previous -** instruction. +** Check whether instruction uses top from previous instruction, that is, +** it accepts multiple results. */ int luaP_isIT (Instruction i) { OpCode op = GET_OPCODE(i); switch (op) { case OP_SETLIST: - return GETARG_vB(i) == 0; - case OP_VARARGPREP: - return 1; + return testITMode(GET_OPCODE(i)) && GETARG_vB(i) == 0; default: return testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0; } diff --git a/lopcodes.h b/lopcodes.h index 86cff065..b6bd182e 100644 --- a/lopcodes.h +++ b/lopcodes.h @@ -417,8 +417,8 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ ** bits 0-2: op mode ** bit 3: instruction set register A ** bit 4: operator is a test (next instruction must be a jump) -** bit 5: used by 'luaP_isIT' -** bit 6: used by 'luaP_isOT' +** bit 5: instruction uses 'L->top' set by previous instruction (when B == 0) +** bit 6: instruction sets 'L->top' for next instruction (when C == 0) ** bit 7: instruction is an MM instruction (call a metamethod) */ @@ -427,17 +427,12 @@ LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];) #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 7)) #define testAMode(m) (luaP_opmodes[m] & (1 << 3)) #define testTMode(m) (luaP_opmodes[m] & (1 << 4)) +#define testITMode(m) (luaP_opmodes[m] & (1 << 5)) +#define testOTMode(m) (luaP_opmodes[m] & (1 << 6)) #define testMMMode(m) (luaP_opmodes[m] & (1 << 7)) -/* Check whether instruction sets top for next instruction, that is, -** it results in multiple values. Used only for tests. -*/ -#define luaP_isOT(i) \ - (GET_OPCODE(i) == OP_TAILCALL || \ - ((luaP_opmodes[GET_OPCODE(i)] & (1 << 6)) && GETARG_C(i) == 0)) - - +LUAI_FUNC int luaP_isOT (Instruction i); LUAI_FUNC int luaP_isIT (Instruction i); diff --git a/loslib.c b/loslib.c index 111ac2f8..b7a2b0d1 100644 --- a/loslib.c +++ b/loslib.c @@ -345,22 +345,11 @@ static int os_date (lua_State *L) { } -static int os_time_aux (lua_State *L, time_t t, int err) { - if (err || t != (time_t)(l_timet)t) - return luaL_error(L, - "time result cannot be represented in this installation"); - l_pushtime(L, t); - return 1; -} - - static int os_time (lua_State *L) { - if (lua_isnoneornil(L, 1)) { /* called without args? */ - time_t t = time(NULL); /* get current time; error if it is -1 */ - return os_time_aux(L, t, (t == (time_t)(-1))); - } + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ else { - time_t t; struct tm ts; luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); /* make sure table is at the top */ @@ -371,12 +360,14 @@ static int os_time (lua_State *L) { ts.tm_min = getfield(L, "min", 0, 0); ts.tm_sec = getfield(L, "sec", 0, 0); ts.tm_isdst = getboolfield(L, "isdst"); - ts.tm_wday = -1; /* if call succeeds, it will set this value */ t = mktime(&ts); setallfields(L, &ts); /* update fields with normalized values */ - /* error if tm_wday was not set */ - return os_time_aux(L, t, ts.tm_wday == -1); } + 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; } @@ -416,17 +407,17 @@ static int os_exit (lua_State *L) { 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}, + {"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}, + {"time", os_time}, + {"tmpname", os_tmpname}, {NULL, NULL} }; diff --git a/lparser.c b/lparser.c index 3c26a4fd..b3855d4c 100644 --- a/lparser.c +++ b/lparser.c @@ -821,7 +821,8 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { luaC_objbarrier(L, f, f->source); f->maxstacksize = 2; /* registers 0/1 are always valid */ fs->kcache = luaH_new(L); /* create table for function */ - luaD_anchorobj(L, ls->h, obj2gco(fs->kcache)); /* anchor it */ + sethvalue2s(L, L->top.p, fs->kcache); /* anchor it */ + luaD_inctop(L); enterblock(fs, bl, 0); } @@ -830,7 +831,6 @@ static void close_func (LexState *ls) { lua_State *L = ls->L; FuncState *fs = ls->fs; Proto *f = fs->f; - TValue temp; luaK_ret(fs, luaY_nvarstack(fs), 0); /* final return */ leaveblock(fs); lua_assert(fs->bl == NULL); @@ -843,10 +843,8 @@ static void close_func (LexState *ls) { 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); - /* remove kcache table from scanner table ("weigh" its anchor) */ - sethvalue(L, &temp, fs->kcache); /* key to be set to nil */ - luaH_set(L, ls->h, &temp, &G(L)->nilvalue); ls->fs = fs->prev; + L->top.p--; /* pop kcache table */ luaC_checkGC(L); } @@ -1166,7 +1164,6 @@ static void funcargs (LexState *ls, expdesc *f) { } default: { luaX_syntaxerror(ls, "function arguments expected"); - return; /* to avoid warnings */ } } lua_assert(f->k == VNONRELOC); @@ -1614,6 +1611,7 @@ static void repeatstat (LexState *ls, int line) { 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 */ @@ -1622,7 +1620,6 @@ static void repeatstat (LexState *ls, int line) { luaK_patchtohere(fs, exit); /* normal exit comes to here */ } luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ - leaveblock(fs); /* finish scope */ leaveblock(fs); /* finish loop */ } @@ -2114,7 +2111,7 @@ static void statement (LexState *ls) { gotostat(ls, line); break; } -#if LUA_COMPAT_GLOBAL +#if defined(LUA_COMPAT_GLOBAL) case TK_NAME: { /* compatibility code to parse global keyword when "global" is not reserved */ @@ -2168,14 +2165,16 @@ static void mainfunc (LexState *ls, FuncState *fs) { } -LClosure *luaY_parser (lua_State *L, ZIO *z, Table *anchor, Mbuffer *buff, +LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Dyndata *dyd, const char *name, int firstchar) { LexState lexstate; FuncState funcstate; - LClosure *cl; - lexstate.h = anchor; /* table for scanner */ - cl = luaF_newLclosure(L, 1); /* create main closure */ - luaD_anchorobj(L, anchor, obj2gco(cl)); /* anchor it in scanner table */ + LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ + setclLvalue2s(L, L->top.p, cl); /* anchor it (to avoid being collected) */ + luaD_inctop(L); + lexstate.h = luaH_new(L); /* create table for scanner */ + sethvalue2s(L, L->top.p, 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 */ @@ -2188,6 +2187,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Table *anchor, Mbuffer *buff, 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); - return cl; + L->top.p--; /* remove scanner's table */ + return cl; /* closure is on the stack, too */ } diff --git a/lparser.h b/lparser.h index 4fad6bdc..a30df04f 100644 --- a/lparser.h +++ b/lparser.h @@ -189,9 +189,8 @@ typedef struct FuncState { 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, Table *anchor, - Mbuffer *buff, Dyndata *dyd, - const char *name, int firstchar); +LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); #endif diff --git a/lstate.c b/lstate.c index ada0b856..70a11aae 100644 --- a/lstate.c +++ b/lstate.c @@ -68,19 +68,14 @@ void luaE_setdebt (global_State *g, l_mem debt) { } -CallInfo *luaE_extendCI (lua_State *L, int err) { +CallInfo *luaE_extendCI (lua_State *L) { CallInfo *ci; - ci = luaM_reallocvector(L, NULL, 0, 1, CallInfo); - if (l_unlikely(ci == NULL)) { /* allocation failed? */ - if (err) - luaM_error(L); /* raise the error */ - return NULL; /* else only report it */ - } - ci->next = L->ci->next; - ci->previous = L->ci; + lua_assert(L->ci->next == NULL); + ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); L->ci->next = ci; - if (ci->next) - ci->next->previous = ci; + ci->previous = L->ci; + ci->next = NULL; ci->u.l.trap = 0; L->nci++; return ci; @@ -151,7 +146,7 @@ LUAI_FUNC void luaE_incCstack (lua_State *L) { static void resetCI (lua_State *L) { CallInfo *ci = L->ci = &L->base_ci; ci->func.p = L->stack.p; - setnilvalue2s(ci->func.p); /* 'function' entry for basic 'ci' */ + setnilvalue(s2v(ci->func.p)); /* 'function' entry for basic 'ci' */ ci->top.p = ci->func.p + 1 + LUA_MINSTACK; /* +1 for 'function' entry */ ci->u.c.k = NULL; ci->callstatus = CIST_C; @@ -166,7 +161,7 @@ static void stack_init (lua_State *L1, lua_State *L) { L1->stack.p = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); L1->tbclist.p = L1->stack.p; for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++) - setnilvalue2s(L1->stack.p + i); /* erase new stack */ + setnilvalue(s2v(L1->stack.p + i)); /* erase new stack */ L1->stack_last.p = L1->stack.p + BASIC_STACK_SIZE; /* initialize first ci */ resetCI(L1); diff --git a/lstate.h b/lstate.h index 30a560a7..20dc4d24 100644 --- a/lstate.h +++ b/lstate.h @@ -383,7 +383,7 @@ typedef struct global_State { /* -** Union of all collectable objects +** Union of all collectable objects (only for conversions) ** ISO C99, 6.5.2.3 p.5: ** "if a union contains several structures that share a common initial ** sequence [...], and if the union object currently contains one @@ -403,32 +403,32 @@ union GCUnion { }; -/* macros to convert a GCObject into a specific value -** ISO C99, 6.3.2.2 p.7: -** "A pointer to an object or incomplete type may be converted to a -** pointer to a different object or incomplete type. If the resulting -** pointer is not correctly aligned for the pointed-to type, the -** behavior is undefined. Otherwise, when converted back again, the -** result shall compare equal to the original pointer." +/* +** ISO C99, 6.7.2.1 p.14: +** "A pointer to a union object, suitably converted, points to each of +** its members [...], and vice versa." */ -#define gco2(v,T,o) check_exp((o)->tt == v, cast(T*, o)) -#define gco2nv(t,T,o) check_exp(novariant((o)->tt) == t, cast(T*, o)) -#define gco2ts(o) gco2nv(LUA_TSTRING, TString, o) -#define gco2u(o) gco2(LUA_VUSERDATA, Udata, o) -#define gco2lcl(o) (&gco2(LUA_VLCL, Closure, o)->l) -#define gco2ccl(o) (&gco2(LUA_VCCL, Closure, o)->c) -#define gco2cl(o) gco2nv(LUA_TFUNCTION, Closure, o) -#define gco2t(o) gco2(LUA_VTABLE, Table, o) -#define gco2p(o) gco2(LUA_VPROTO, Proto, o) -#define gco2th(o) gco2(LUA_VTHREAD, lua_State, o) -#define gco2upv(o) gco2(LUA_VUPVAL, UpVal, o) +#define cast_u(o) cast(union GCUnion *, (o)) + +/* macros to convert a GCObject into a specific value */ +#define gco2ts(o) \ + check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) +#define gco2u(o) check_exp((o)->tt == LUA_VUSERDATA, &((cast_u(o))->u)) +#define gco2lcl(o) check_exp((o)->tt == LUA_VLCL, &((cast_u(o))->cl.l)) +#define gco2ccl(o) check_exp((o)->tt == LUA_VCCL, &((cast_u(o))->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) +#define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h)) +#define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p)) +#define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th)) +#define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv)) /* ** macro to convert a Lua object into a GCObject */ #define obj2gco(v) \ - check_exp(novariant((v)->tt) >= LUA_TSTRING, cast(GCObject*, v)) + check_exp(novariant((v)->tt) >= LUA_TSTRING, &(cast_u(v)->gc)) /* actual number of total memory allocated */ @@ -438,7 +438,7 @@ union GCUnion { 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, int err); +LUAI_FUNC CallInfo *luaE_extendCI (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); diff --git a/lstrlib.c b/lstrlib.c index dd3c0fd0..23df839e 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -141,8 +141,8 @@ static int str_rep (lua_State *L) { const char *s = luaL_checklstring(L, 1, &len); lua_Integer n = luaL_checkinteger(L, 2); const char *sep = luaL_optlstring(L, 3, "", &lsep); - if (n <= 0 || (len | lsep) == 0) - lua_pushliteral(L, ""); /* no repetitions or both strings empty */ + if (n <= 0) + lua_pushliteral(L, ""); else if (l_unlikely(len > MAX_SIZE - lsep || cast_st2S(len + lsep) > cast_st2S(MAX_SIZE) / n)) return luaL_error(L, "resulting string too large"); @@ -757,25 +757,19 @@ static int nospecials (const char *p, size_t l) { } -/* -** Prepare state for matches. These fields are not affected by each match. -*/ 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; } -/* -** (Re)prepare state for a match, setting fields that change during -** each match. -*/ static void reprepstate (MatchState *ms) { - ms->matchdepth = MAXCCALLS; ms->level = 0; + lua_assert(ms->matchdepth == MAXCCALLS); } @@ -974,7 +968,7 @@ static int str_gsub (lua_State *L) { 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; + changed = add_value(&ms, &b, src, e, tr) | changed; src = lastmatch = e; } else if (src < ms.src_end) /* otherwise, skip one character */ @@ -1732,7 +1726,7 @@ static int str_packsize (lua_State *L) { luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1, "variable-length format"); size += ntoalign; /* total space used by option */ - luaL_argcheck(L, totalsize <= MAX_SIZE - size, + luaL_argcheck(L, totalsize <= LUA_MAXINTEGER - size, 1, "format result too large"); totalsize += size; } diff --git a/ltable.c b/ltable.c index 2f2b5c1f..b7f88f6f 100644 --- a/ltable.c +++ b/ltable.c @@ -651,9 +651,10 @@ static void reinserthash (lua_State *L, Table *ot, Table *t) { /* -** Exchange the hash part of 't1' and 't2'. (In 'flags', only the dummy -** bit must be exchanged: The metamethod bits do not change during a -** resize, so the "real" table can keep their values.) +** Exchange the hash part of 't1' and 't2'. (In 'flags', only the +** dummy bit must be exchanged: The 'isrealasize' is not related +** to the hash part, and the metamethod bits do not change during +** a resize, so the "real" table can keep their values.) */ static void exchangehashpart (Table *t1, Table *t2) { lu_byte lsizenode = t1->lsizenode; @@ -1155,15 +1156,14 @@ void luaH_finishset (lua_State *L, Table *t, const TValue *key, lua_assert(hres != HOK); if (hres == HNOTFOUND) { TValue aux; - const TValue *actk = key; /* actual key to insert */ 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)) { /* is key equal to an integer? */ - setivalue(&aux, k); - actk = &aux; /* use the integer as the key */ + if (luaV_flttointeger(f, &k, F2Ieq)) { + setivalue(&aux, k); /* key is equal to an integer */ + key = &aux; /* insert it as an integer */ } else if (l_unlikely(luai_numisnan(f))) luaG_runerror(L, "table index is NaN"); @@ -1176,7 +1176,7 @@ void luaH_finishset (lua_State *L, Table *t, const TValue *key, L->top.p--; return; } - luaH_newkey(L, t, actk, value); + luaH_newkey(L, t, key, value); } else if (hres > 0) { /* regular Node? */ setobj2t(L, gval(gnode(t, hres - HFIRSTNODE)), value); diff --git a/ltablib.c b/ltablib.c index 15c3c09f..46ecb5e0 100644 --- a/ltablib.c +++ b/ltablib.c @@ -42,17 +42,15 @@ static int checkfield (lua_State *L, const char *key, int n) { /* ** Check that 'arg' either is a table or can behave like one (that is, -** has a metatable with the required metamethods). +** has a metatable with the required metamethods) */ static void checktab (lua_State *L, int arg, int what) { - int tp = lua_type(L, arg); - if (tp != LUA_TTABLE) { /* is it not a table? */ + 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) || /* strings don't need '__len' to have a length */ - tp == LUA_TSTRING || checkfield(L, "__len", ++n))) { + (!(what & TAB_L) || checkfield(L, "__len", ++n))) { lua_pop(L, n); /* pop metatable and tested metamethods */ } else @@ -206,9 +204,8 @@ static int tpack (lua_State *L) { static int tunpack (lua_State *L) { lua_Unsigned n; - lua_Integer len = aux_getn(L, 1, TAB_R); lua_Integer i = luaL_optinteger(L, 2, 1); - lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, len); + lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); if (i > e) return 0; /* empty range */ n = l_castS2U(e) - l_castS2U(i); /* number of elements minus 1 */ if (l_unlikely(n >= (unsigned int)INT_MAX || diff --git a/ltests.c b/ltests.c index 2bf5545a..c4905f94 100644 --- a/ltests.c +++ b/ltests.c @@ -1106,27 +1106,6 @@ static int stacklevel (lua_State *L) { } -static int resetCI (lua_State *L) { - CallInfo *ci = L->ci; - while (ci->next != NULL) { - CallInfo *tofree = ci->next; - ci->next = ci->next->next; - luaM_free(L, tofree); - L->nci--; - } - return 0; -} - - -static int reallocstack (lua_State *L) { - int n = cast_int(luaL_checkinteger(L, 1)); - lua_lock(L); - luaD_reallocstack(L, cast_int(L->top.p - L->stack.p) + n, 1); - lua_unlock(L); - return 0; -} - - static int table_query (lua_State *L) { const Table *t; int i = cast_int(luaL_optinteger(L, 2, -1)); @@ -1145,7 +1124,7 @@ static int table_query (lua_State *L) { if (!tagisempty(*getArrTag(t, i))) arr2obj(t, cast_uint(i), s2v(L->top.p)); else - setnilvalue2s(L->top.p); + setnilvalue(s2v(L->top.p)); api_incr_top(L); lua_pushnil(L); } @@ -1302,7 +1281,7 @@ static int doonnewstack (lua_State *L) { lua_State *L1 = lua_newthread(L); size_t l; const char *s = luaL_checklstring(L, 1, &l); - int status = luaL_loadbufferx(L1, s, l, s, "t"); + int status = luaL_loadbuffer(L1, s, l, s); if (status == LUA_OK) status = lua_pcall(L1, 0, 0, 0); lua_pushinteger(L, status); @@ -1382,7 +1361,7 @@ static int doremote (lua_State *L) { const char *code = luaL_checklstring(L, 2, &lcode); int status; lua_settop(L1, 0); - status = luaL_loadbufferx(L1, code, lcode, code, "t"); + status = luaL_loadbuffer(L1, code, lcode, code); if (status == LUA_OK) status = lua_pcall(L1, 0, LUA_MULTRET, 0); if (status != LUA_OK) { @@ -1738,7 +1717,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { lua_pushinteger(L1, luaL_len(L1, getindex)); } else if EQ("loadfile") { - luaL_loadfilex(L1, luaL_checkstring(L1, getnum), "t"); + luaL_loadfile(L1, luaL_checkstring(L1, getnum)); } else if EQ("loadstring") { size_t slen; @@ -2203,8 +2182,6 @@ static const struct luaL_Reg tests_funcs[] = { {"s2d", s2d}, {"sethook", sethook}, {"stacklevel", stacklevel}, - {"resetCI", resetCI}, - {"reallocstack", reallocstack}, {"sizes", get_sizes}, {"testC", testC}, {"makeCfunc", makeCfunc}, diff --git a/ltests.h b/ltests.h index f5f14cd6..93096da8 100644 --- a/ltests.h +++ b/ltests.h @@ -14,7 +14,6 @@ /* test Lua with compatibility code */ #define LUA_COMPAT_MATHLIB #undef LUA_COMPAT_GLOBAL -#define LUA_COMPAT_GLOBAL 0 #define LUA_DEBUG diff --git a/ltm.c b/ltm.c index cfe90e30..f2a373f8 100644 --- a/ltm.c +++ b/ltm.c @@ -262,7 +262,7 @@ static void buildhiddenargs (lua_State *L, CallInfo *ci, const Proto *p, /* move fixed parameters to after the copied function */ for (i = 1; i <= nfixparams; i++) { setobjs2s(L, L->top.p++, ci->func.p + i); - setnilvalue2s(ci->func.p + i); /* erase original parameter (for GC) */ + setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */ } ci->func.p += totalargs + 1; /* 'func' now lives after hidden arguments */ ci->top.p += totalargs + 1; @@ -283,7 +283,7 @@ void luaT_adjustvarargs (lua_State *L, CallInfo *ci, const Proto *p) { lua_assert(p->flag & PF_VAHID); buildhiddenargs(L, ci, p, totalargs, nfixparams, nextra); /* set vararg parameter to nil */ - setnilvalue2s(ci->func.p + nfixparams + 1); + setnilvalue(s2v(ci->func.p + nfixparams + 1)); lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p); } } @@ -307,7 +307,7 @@ void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc) { return; } } - setnilvalue2s(ra); /* else produce nil */ + setnilvalue(s2v(ra)); /* else produce nil */ } @@ -355,10 +355,10 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted, for (i = 0; i < touse; i++) { lu_byte tag = luaH_getint(h, i + 1, s2v(where + i)); if (tagisempty(tag)) - setnilvalue2s(where + i); + setnilvalue(s2v(where + i)); } } for (; i < wanted; i++) /* complete required results with nil */ - setnilvalue2s(where + i); + setnilvalue(s2v(where + i)); } diff --git a/ltm.h b/ltm.h index afc7ad00..07fc8c1c 100644 --- a/ltm.h +++ b/ltm.h @@ -49,7 +49,7 @@ 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 6 of the flag indicates that -** the table is using the dummy node.) +** the table is using the dummy node; bit 7 is used for 'isrealasize'.) */ #define maskflags cast_byte(~(~0u << (TM_EQ + 1))) diff --git a/lua.c b/lua.c index 858a04c0..5054583d 100644 --- a/lua.c +++ b/lua.c @@ -30,12 +30,6 @@ #define LUA_INIT_VAR "LUA_INIT" #endif -/* Name of the environment variable with the name of the readline library */ -#if !defined(LUA_RLLIB_VAR) -#define LUA_RLLIB_VAR "LUA_READLINELIB" -#endif - - #define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX @@ -207,12 +201,12 @@ static int dochunk (lua_State *L, int status) { static int dofile (lua_State *L, const char *name) { - return dochunk(L, luaL_loadfilex(L, name, "bt")); + return dochunk(L, luaL_loadfile(L, name)); } static int dostring (lua_State *L, const char *s, const char *name) { - return dochunk(L, luaL_loadbufferx(L, s, strlen(s), name, "t")); + return dochunk(L, luaL_loadbuffer(L, s, strlen(s), name)); } @@ -266,7 +260,7 @@ static int handle_script (lua_State *L, char **argv) { const char *fname = argv[0]; if (strcmp(fname, "-") == 0 && strcmp(argv[-1], "--") != 0) fname = NULL; /* stdin */ - status = luaL_loadfilex(L, fname, "bt"); + status = luaL_loadfile(L, fname); if (status == LUA_OK) { int n = pushargs(L); /* push arguments to script */ status = docall(L, n, LUA_MULTRET); @@ -380,21 +374,12 @@ static int runargs (lua_State *L, char **argv, int n) { } -static char *(*l_getenv)(const char *name); - -/* Function to ignore environment variables, used by option -E */ -static char *no_getenv (const char *name) { - UNUSED(name); - return NULL; -} - - static int handle_luainit (lua_State *L) { const char *name = "=" LUA_INITVARVERSION; - const char *init = l_getenv(name + 1); + const char *init = getenv(name + 1); if (init == NULL) { name = "=" LUA_INIT_VAR; - init = l_getenv(name + 1); /* try alternative name */ + init = getenv(name + 1); /* try alternative name */ } if (init == NULL) return LUA_OK; else if (init[0] == '@') @@ -513,24 +498,18 @@ static void lua_freeline (char *line) { #include static void lua_initreadline (lua_State *L) { - const char *rllib = l_getenv(LUA_RLLIB_VAR); /* name of readline library */ - void *lib; /* library handle */ - if (rllib == NULL) /* no environment variable? */ - rllib = LUA_READLINELIB; /* use default name */ - lib = dlopen(rllib, RTLD_NOW | RTLD_LOCAL); - if (lib != NULL) { + void *lib = dlopen(LUA_READLINELIB, RTLD_NOW | RTLD_LOCAL); + if (lib == NULL) + lua_warning(L, "library '" LUA_READLINELIB "' not found", 0); + else { const char **name = cast(const char**, dlsym(lib, "rl_readline_name")); if (name != NULL) *name = "lua"; l_readline = cast(l_readlineT, cast_func(dlsym(lib, "readline"))); l_addhist = cast(l_addhistT, cast_func(dlsym(lib, "add_history"))); - if (l_readline != NULL) /* could load readline function? */ - return; /* everything ok */ - /* else emit a warning */ + if (l_readline == NULL) + lua_warning(L, "unable to load 'readline'", 0); } - lua_warning(L, "unable to load readline library '", 1); - lua_warning(L, rllib, 1); - lua_warning(L, "'", 0); } #else /* }{ */ @@ -609,11 +588,11 @@ static int pushline (lua_State *L, int firstline) { static int addreturn (lua_State *L) { const char *line = lua_tostring(L, -1); /* original line */ const char *retline = lua_pushfstring(L, "return %s;", line); - int status = luaL_loadbufferx(L, retline, strlen(retline), "=stdin", "t"); + int status = luaL_loadbuffer(L, retline, strlen(retline), "=stdin"); if (status == LUA_OK) lua_remove(L, -2); /* remove modified line */ else - lua_pop(L, 2); /* pop result from 'luaL_loadbufferx' and modified line */ + lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */ return status; } @@ -640,7 +619,7 @@ static int multiline (lua_State *L) { const char *line = lua_tolstring(L, 1, &len); /* get first line */ checklocal(line); for (;;) { /* repeat until gets a complete statement */ - int status = luaL_loadbufferx(L, line, len, "=stdin", "t"); /* try it */ + int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ if (!incomplete(L, status) || !pushline(L, 0)) return status; /* should not or cannot try to add continuation line */ lua_remove(L, -2); /* remove error message (from incomplete line) */ @@ -714,13 +693,7 @@ static void doREPL (lua_State *L) { /* }================================================================== */ #if !defined(luai_openlibs) -#if defined(LUA_NODEBUGLIB) -/* With this option, code must require the debug library before using it */ -#define luai_openlibs(L) luaL_openselectedlibs(L, ~LUA_DBLIBK, LUA_DBLIBK) -#else -/* The default is to open all standard libraries */ -#define luai_openlibs(L) luaL_openselectedlibs(L, ~0, 0) -#endif +#define luai_openlibs(L) luaL_openselectedlibs(L, ~0, 0) #endif @@ -742,18 +715,17 @@ static int pmain (lua_State *L) { if (args & has_v) /* option '-v'? */ print_version(); if (args & has_E) { /* option '-E'? */ - l_getenv = &no_getenv; /* program will ignore environment variables */ lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); } - else - l_getenv = &getenv; luai_openlibs(L); /* open standard libraries */ createargtable(L, argv, argc, script); /* create table 'arg' */ lua_gc(L, LUA_GCRESTART); /* start GC... */ lua_gc(L, LUA_GCGEN); /* ...in generational mode */ - if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */ - return 0; /* error running LUA_INIT */ + if (!(args & has_E)) { /* no option '-E'? */ + if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */ + return 0; /* error running LUA_INIT */ + } if (!runargs(L, argv, optlim)) /* execute arguments -e, -l, and -W */ return 0; /* something failed */ if (script > 0) { /* execute main script (if there is one) */ diff --git a/lua.h b/lua.h index 6deaed49..ab473dc3 100644 --- a/lua.h +++ b/lua.h @@ -13,13 +13,13 @@ #include -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2026 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 1 +#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) @@ -521,7 +521,7 @@ struct lua_Debug { /****************************************************************************** -* Copyright (C) 1994-2026 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/luaconf.h b/luaconf.h index bdac085c..96a77802 100644 --- a/luaconf.h +++ b/luaconf.h @@ -70,16 +70,14 @@ #if defined(LUA_USE_LINUX) #define LUA_USE_POSIX #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ -#if !defined(LUA_READLINELIB) #define LUA_READLINELIB "libreadline.so" #endif -#endif #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX #define LUA_USE_DLOPEN /* macOS does not need -ldl */ -#define LUA_USE_READLINE /* needs an extra library: -lreadline */ +#define LUA_READLINELIB "libedit.dylib" #endif @@ -226,17 +224,17 @@ #if !defined(LUA_PATH_DEFAULT) #define LUA_PATH_DEFAULT \ - LUA_LDIR "?.lua;" LUA_LDIR "?\\init.lua;" \ - LUA_CDIR "?.lua;" LUA_CDIR "?\\init.lua;" \ - LUA_SHRDIR "?.lua;" LUA_SHRDIR "?\\init.lua;" \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ + LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ ".\\?.lua;" ".\\?\\init.lua" #endif #if !defined(LUA_CPATH_DEFAULT) #define LUA_CPATH_DEFAULT \ - LUA_CDIR "?.dll;" \ - LUA_CDIR "..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ - LUA_CDIR "loadall.dll;" ".\\?.dll" + LUA_CDIR"?.dll;" \ + LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ + LUA_CDIR"loadall.dll;" ".\\?.dll" #endif #else /* }{ */ @@ -247,14 +245,14 @@ #if !defined(LUA_PATH_DEFAULT) #define LUA_PATH_DEFAULT \ - LUA_LDIR "?.lua;" LUA_LDIR "?/init.lua;" \ - LUA_CDIR "?.lua;" LUA_CDIR "?/init.lua;" \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ "./?.lua;" "./?/init.lua" #endif #if !defined(LUA_CPATH_DEFAULT) #define LUA_CPATH_DEFAULT \ - LUA_CDIR "?.so;" LUA_CDIR "loadall.so;" "./?.so" + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" #endif #endif /* } */ @@ -341,9 +339,7 @@ /* @@ LUA_COMPAT_GLOBAL avoids 'global' being a reserved word */ -#if !defined(LUA_COMPAT_GLOBAL) -#define LUA_COMPAT_GLOBAL 1 -#endif +#define LUA_COMPAT_GLOBAL /* @@ -653,7 +649,7 @@ */ #if !defined(luai_likely) -#if !defined(LUA_NOBUILTIN) && defined(__GNUC__) && (__GNUC__ >= 3) +#if defined(__GNUC__) && !defined(LUA_NOBUILTIN) #define luai_likely(x) (__builtin_expect(((x) != 0), 1)) #define luai_unlikely(x) (__builtin_expect(((x) != 0), 0)) #else @@ -725,17 +721,10 @@ /* -@@ LUAI_MAXALIGN defines fields that ensure proper alignment for -** memory areas offered by Lua (e.g., userdata memory). -** Add fields to it if you need alignment for non-ISO objects. +@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure +** maximum alignment for the other items in that union. */ -#if defined(LLONG_MAX) -/* use ISO C99 stuff */ -#define LUAI_MAXALIGN long double u; void *s; long long l -#else -/* use only C89 stuff */ #define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l -#endif /* }================================================================== */ diff --git a/lundump.c b/lundump.c index d5fdc64b..3b61cc8c 100644 --- a/lundump.c +++ b/lundump.c @@ -392,8 +392,7 @@ static void checkHeader (LoadState *S) { /* ** Load precompiled chunk. */ -LClosure *luaU_undump (lua_State *L, ZIO *Z, Table *anchor, const char *name, - int fixed) { +LClosure *luaU_undump (lua_State *L, ZIO *Z, const char *name, int fixed) { LoadState S; LClosure *cl; if (*name == '@' || *name == '=') @@ -406,16 +405,20 @@ LClosure *luaU_undump (lua_State *L, ZIO *Z, Table *anchor, const char *name, S.fixed = cast_byte(fixed); S.offset = 1; /* fist byte was already read */ checkHeader(&S); - S.h = anchor; - S.nstr = 0; cl = luaF_newLclosure(L, loadByte(&S)); - luaD_anchorobj(L, anchor, obj2gco(cl)); + setclLvalue2s(L, L->top.p, cl); + luaD_inctop(L); + S.h = luaH_new(L); /* create list of saved strings */ + S.nstr = 0; + sethvalue2s(L, L->top.p, S.h); /* anchor it */ + luaD_inctop(L); cl->p = luaF_newproto(L); luaC_objbarrier(L, cl, cl->p); loadFunction(&S, cl->p); if (cl->nupvalues != cl->p->sizeupvalues) error(&S, "corrupted chunk"); luai_verifycode(L, cl->p); + L->top.p--; /* pop table */ return cl; } diff --git a/lundump.h b/lundump.h index 186e25f8..c4e06f9e 100644 --- a/lundump.h +++ b/lundump.h @@ -30,8 +30,8 @@ /* load one chunk; from lundump.c */ -LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, Table *anchor, - const char* name, int fixed); +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/lutf8lib.c b/lutf8lib.c index 0cd7f9c3..b7f3fe1e 100644 --- a/lutf8lib.c +++ b/lutf8lib.c @@ -56,8 +56,6 @@ static const char *utf8_decode (const char *s, l_uint32 *val, int strict) { l_uint32 res = 0; /* final result */ if (c < 0x80) /* ASCII? */ res = c; - else if (c >= 0xfe) /* c >= 1111 1110b ? */ - return NULL; /* would need six or more continuation bytes */ else { int count = 0; /* to count number of continuation bytes */ for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ @@ -66,9 +64,8 @@ static const char *utf8_decode (const char *s, l_uint32 *val, int strict) { return NULL; /* invalid byte sequence */ res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ } - lua_assert(count <= 5); res |= ((l_uint32)(c & 0x7F) << (count * 5)); /* add first byte */ - if (res > MAXUTF || res < limits[count]) + if (count > 5 || res > MAXUTF || res < limits[count]) return NULL; /* invalid byte sequence */ s += count; /* skip continuation bytes read */ } @@ -149,7 +146,7 @@ static int codepoint (lua_State *L) { 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", cast(unsigned long, code)); + lua_pushfstring(L, "%U", (long)code); } diff --git a/lvm.c b/lvm.c index 46170534..c70e2b8a 100644 --- a/lvm.c +++ b/lvm.c @@ -268,9 +268,9 @@ static int forprep (lua_State *L, StkId ra) { /* ** Execute a step of a float numerical for loop, returning ** true iff the loop must continue. (The integer case is -** written inline with opcode OP_FORLOOP, for performance.) +** written online with opcode OP_FORLOOP, for performance.) */ -static int floatforloop (lua_State *L, StkId ra) { +static int floatforloop (StkId ra) { lua_Number step = fltvalue(s2v(ra + 1)); lua_Number limit = fltvalue(s2v(ra)); lua_Number idx = fltvalue(s2v(ra + 2)); /* control variable */ @@ -303,7 +303,7 @@ lu_byte luaV_finishget (lua_State *L, const TValue *t, TValue *key, else { /* 't' is a table */ tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ if (tm == NULL) { /* no metamethod? */ - setnilvalue2s(val); /* result is nil */ + setnilvalue(s2v(val)); /* result is nil */ return LUA_VNIL; } /* else will try the metamethod */ @@ -360,19 +360,13 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, luaT_callTM(L, tm, t, key, val); return; } - t = tm; /* else must repeat assignment over 'tm' */ - /* do the equivalent to 'luaV_fastset', but saving 'h' */ - if (!ttistable(t)) - hres = HNOTATABLE; - else { - Table *h = hvalue(t); /* next call can change the value at 't' */ - hres = luaH_pset(h, key, val); - if (hres == HOK) { - luaC_barrierback(L, obj2gco(h), val); /* luaV_finishfastset */ - return; /* done */ - } + t = tm; /* else repeat assignment over 'tm' */ + luaV_fastset(t, key, val, hres, luaH_pset); + if (hres == HOK) { + luaV_finishfastset(L, t, val); + return; /* done */ } - /* else 'return luaV_finishset(L, t, key, val, hres)' (loop) */ + /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ } luaG_runerror(L, "'__newindex' chain too long; possible loop"); } @@ -925,7 +919,7 @@ void luaV_finishOp (lua_State *L) { ** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute' ** ** All these macros are to be used exclusively inside the main -** interpreter loop (function luaV_execute) and may access directly +** iterpreter loop (function luaV_execute) and may access directly ** the local variables of that function (L, i, pc, ci, etc.). ** =================================================================== */ @@ -1117,7 +1111,7 @@ void luaV_finishOp (lua_State *L) { -#define updatetrap(ci) (trap = cast_int(ci->u.l.trap)) +#define updatetrap(ci) (trap = ci->u.l.trap) #define updatebase(ci) (base = ci->func.p + 1) @@ -1211,7 +1205,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { #include "ljumptab.h" #endif startfunc: - trap = cast_int(L->hookmask); + trap = L->hookmask; returning: /* trap already set */ cl = ci_func(ci); k = cl->p->k; @@ -1847,7 +1841,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { pc -= GETARG_Bx(i); /* jump back */ } } - else if (floatforloop(L, ra)) /* float loop */ + else if (floatforloop(ra)) /* float loop */ pc -= GETARG_Bx(i); /* jump back */ updatetrap(ci); /* allows a signal to break the loop */ vmbreak; diff --git a/makefile b/makefile index 8144dcb6..8674519f 100644 --- a/makefile +++ b/makefile @@ -60,29 +60,24 @@ CWARNS= $(CWARNSCPP) $(CWARNSC) $(CWARNGCC) # create problems; some are only available in newer gcc versions. To # use some of them, we also have to define an environment variable # ASAN_OPTIONS="detect_invalid_pointer_pairs=2". -# -fsanitize=undefined (you may need to add "-lubsan" to libs) +# -fsanitize=undefined # -fsanitize=pointer-subtract -fsanitize=address -fsanitize=pointer-compare - -# Test mode: Add test library, turn on asserts, redefine several -# constants ("to give some bugs a chance"), track memory use, and add -# debug information. # TESTS= -DLUA_USER_H='"ltests.h"' -Og -g + LOCAL = $(TESTS) $(CWARNS) # To enable Linux goodies, -DLUA_USE_LINUX # For C89, "-std=c89 -DLUA_USE_C89" # Note that Linux/Posix options are not compatible with C89 -# (For 32-bit, add option "-m32" to MYCFLAGS and MYLDFLAGS.) MYCFLAGS= $(LOCAL) -std=c99 -DLUA_USE_LINUX MYLDFLAGS= -Wl,-E MYLIBS= -ldl CC= gcc -# (Optionally we can use -march=native -mno-avx512f.) -CFLAGS= -Wall -O2 $(MYCFLAGS) -fno-stack-protector -fno-common +CFLAGS= -Wall -O2 $(MYCFLAGS) -fno-stack-protector -fno-common -march=native AR= ar rc RANLIB= ranlib RM= rm -f diff --git a/manual/2html b/manual/2html index 23f37ac6..b7afd2a6 100755 --- a/manual/2html +++ b/manual/2html @@ -1,4 +1,4 @@ -#!/usr/bin/env lua +#!/usr/bin/env lua5.3 -- special marks: @@ -30,7 +30,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes

Copyright -© 2026 Lua.org, PUC-Rio. All rights reserved. +© 2025 Lua.org, PUC-Rio. All rights reserved.


@@ -58,7 +58,7 @@ end local function compose (f,g) assert(f and g) - return function (...) return g(f(...)) end + return function (s) return g(f(s)) end end local function concat (f, g) @@ -395,10 +395,9 @@ APIEntry = function (e) local apiicmd, ne = string.match(e, "^(.-)(.*)") --io.stderr:write(e) if not apiicmd then - return antipara(Tag.hr() .. Tag.h3(a)) .. Tag.pre(h, {class="api"}) .. e + return antipara(Tag.hr() .. Tag.h3(a)) .. Tag.pre(h) .. e else - return antipara(Tag.hr() .. Tag.h3(a)) .. apiicmd .. - Tag.pre(h, {class="api"}) .. ne + return antipara(Tag.hr() .. Tag.h3(a)) .. apiicmd .. Tag.pre(h) .. ne end end, diff --git a/manual/manual.of b/manual/manual.of index e3c7cd25..5fa4e097 100644 --- a/manual/manual.of +++ b/manual/manual.of @@ -1728,7 +1728,7 @@ global X , _G X = 1 -- ERROR _ENV.X = 1 -- Ok _G.print(X) -- Ok -foo() -- 'foo' can freely change any global +foo() -- 'foo' can freely change any global } A chunk is also a block @see{chunks}, @@ -2692,19 +2692,7 @@ which behaves like a nil value. @sect3{constchar|@title{Pointers to Strings} -Several functions in the API have parameters -that are pointers to C strings (@T{const char*}). -Some of these parameters have an associated length (@T{size_t}). -Unless stated otherwise, -when there is an associated length, -the string can contain embedded zeros; -moreover, the pointer can be @id{NULL} if the length is zero. -When there is no associated length, -the pointer must point to a zero-terminated string. -In any case, the string contents should remain unchanged -until the function returns. - -Several functions in the API also return pointers (@T{const char*}) +Several functions in the API return pointers (@T{const char*}) to Lua strings in the stack. (See @Lid{lua_pushfstring}, @Lid{lua_pushlstring}, @Lid{lua_pushstring}, and @Lid{lua_tolstring}. @@ -3915,12 +3903,8 @@ like any Lua object. This function creates and pushes on the stack a new full userdata, with @id{nuvalue} associated Lua values, called @id{user values}, plus an associated block of raw memory with @id{size} bytes. - -The user values can be set and read with the functions -@Lid{lua_setiuservalue} and @Lid{lua_getiuservalue}. -The block of memory is suitably aligned for any @N{ISO C} object. -(See macro @id{LUAI_MAXALIGN} in file @id{luaconf.h} for other -alignment requirements.) +(The user values can be set and read with the functions +@Lid{lua_setiuservalue} and @Lid{lua_getiuservalue}.) The function returns the address of the block of memory. Lua ensures that this address is valid as long as @@ -3962,8 +3946,8 @@ this confuses the next call to @Lid{lua_next}. This function may raise an error if the given key is neither @nil nor present in the table. - -See function @Lid{next} for more details about the traversal. +See function @Lid{next} for the caveats of modifying +the table during its traversal. } @@ -4448,7 +4432,7 @@ Starts and resumes a coroutine in the given thread @id{L}. To start a coroutine, you push the main function plus any arguments onto the empty stack of the thread. -Then you call @Lid{lua_resume}, +then you call @Lid{lua_resume}, with @id{nargs} being the number of arguments. The function returns when the coroutine suspends, finishes its execution, or raises an unprotected error. @@ -4628,7 +4612,7 @@ You can resume threads with status @Lid{LUA_OK} } @APIEntry{size_t lua_stringtonumber (lua_State *L, const char *s);| -@apii{0,0|1,-} +@apii{0,1,-} Converts the zero-terminated string @id{s} to a number, pushes that number into the stack, @@ -4958,7 +4942,7 @@ Lua calls the given @x{continuation function} @id{k} to continue the execution of the @N{C function} that yielded @see{continuations}. This continuation function receives the same stack from the previous function, -with all the results (@id{nresults}) removed and +with the @id{n} results removed and replaced by the arguments passed to @Lid{lua_resume}. Moreover, the continuation function receives the value @id{ctx} @@ -5048,7 +5032,7 @@ the function was defined in a string where } @item{@id{srclen}| -the length of the string @id{source}. +The length of the string @id{source}. } @item{@id{short_src}| @@ -5212,7 +5196,7 @@ running at the given level; } @item{@Char{S}| -fills in the fields @id{source}, @id{srclen}, @id{short_src}, +fills in the fields @id{source}, @id{short_src}, @id{linedefined}, @id{lastlinedefined}, and @id{what}; } @@ -5388,9 +5372,7 @@ Returns @id{NULL} (and pops nothing) when the index is greater than the number of active local variables. -Parameters @id{ar} and @id{n} are as in the function @Lid{lua_getlocal}, -except that @id{ar} cannot be @id{NULL}, -as @id{lua_setlocal} only operates on activation records. +Parameters @id{ar} and @id{n} are as in the function @Lid{lua_getlocal}. } @@ -6071,14 +6053,6 @@ In both cases, the function pushes onto the stack the final value associated with @id{tname} in the registry. -Usage note: Beware the use of the return value of this function -to conditionally initialize the new metatable -(e.g., by adding metamethods to it). -If the initialization raises an error, -the metatable will not be properly initialized, -but a subsequent execution of that code will detect that the -metatable already exists and then skip the initialization. - } @APIEntry{lua_State *luaL_newstate (void);| @@ -6842,7 +6816,8 @@ for k,v in pairs(t) do @rep{body} end } will iterate over all key@En{}value pairs of table @id{t}. -See function @Lid{next} for more details about the traversal. +See function @Lid{next} for the caveats of modifying +the table during its traversal. } @@ -9132,7 +9107,6 @@ which automatically removes the file when the program ends. This library provides the functionality of the @link{debugI|debug interface} to Lua programs. - You should exert care when using this library. Several of its functions violate basic assumptions about Lua code @@ -9142,8 +9116,6 @@ that userdata metatables cannot be changed by Lua code; that Lua programs do not crash) and therefore can compromise otherwise secure code. Moreover, some functions in this library may be slow. -It is good practice to always require this library explicitly -before using it. All functions in this library are provided inside the @defid{debug} table. @@ -9622,9 +9594,6 @@ change between versions. @item{ The word @Rw{global} is a reserved word. Do not use it as a regular name. - -The compilation option @id{LUA_COMPAT_GLOBAL} (see @id{luaconf.h}) -makes @id{global} a regular word. } @item{ @@ -9756,7 +9725,7 @@ and @bnfNter{LiteralString}, see @See{lexical}.) @OrNL @Rw{local} @Rw{function} @bnfNter{Name} funcbody @OrNL @Rw{global} @Rw{function} @bnfNter{Name} funcbody @OrNL @Rw{local} attnamelist @bnfopt{@bnfter{=} explist} -@OrNL @Rw{global} attnamelist @bnfopt{@bnfter{=} explist} +@OrNL @Rw{global} attnamelist @OrNL @Rw{global} @bnfopt{attrib} @bnfter{*} } diff --git a/testes/calls.lua b/testes/calls.lua index cd4510a2..0dacb85a 100644 --- a/testes/calls.lua +++ b/testes/calls.lua @@ -372,32 +372,6 @@ do -- another bug (in 5.4.0) end -if T then - -- check stack level when calling reader function - local function get (str) - local pos = 0 - local level = nil - return function () - pos = pos + 1 - local c = string.sub(str, pos, pos) - local newlevel = T.stacklevel() - if not level then - level = newlevel - else - assert(level == newlevel) - end - return #c > 0 and c or nil - end - end - - local str = "local function foo () end; return 121" - assert(assert(load(get(str)))() == 121) - - str = string.dump(load(str)) - assert(assert(load(get(str)))() == 121) -end - - x = string.dump(load("x = 1; return x")) a = assert(load(read1(x), nil, "b")) assert(a() == 1 and _G.x == 1) diff --git a/testes/errors.lua b/testes/errors.lua index c82d5b3b..c9d85099 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -159,9 +159,6 @@ assert(not string.find(doit"aaa={13}; local bbbb=1; aaa[bbbb](3)", "'bbbb'")) checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number") checkmessage("aaa=(1)..{}", "a table value") -checkmessage("local function foo (...t) return t.xx + 1 end; foo()", - "field 'xx'") - -- bug in 5.4.6 checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") diff --git a/testes/events.lua b/testes/events.lua index fa9966ab..7e434b1f 100644 --- a/testes/events.lua +++ b/testes/events.lua @@ -390,18 +390,6 @@ do for i=1, 10 do t[i] = 1 end end - -do -- bug since 5.4 - local parent = {} - parent.__newindex = parent - collectgarbage() - local child = setmetatable({}, parent) - child.__newindex = {x = "hello"} - collectgarbage("step") - assert(parent.__newindex.x == "hello") -end - - -- concat metamethod x numbers (bug in 5.1.1) c = {} local x diff --git a/testes/files.lua b/testes/files.lua index 04936565..7146ac7c 100644 --- a/testes/files.lua +++ b/testes/files.lua @@ -854,13 +854,6 @@ local function checkDateTable (t) _G.D = nil end - -do -- testing mktime returning -1 - local t = os.date("*t", -1) - assert(os.time(t) == -1) -end - - checkDateTable(os.time()) if not _port then -- assume that time_t can represent these values diff --git a/testes/gc.lua b/testes/gc.lua index e50d9029..62713dac 100644 --- a/testes/gc.lua +++ b/testes/gc.lua @@ -707,46 +707,4 @@ end collectgarbage(oldmode) - -if T then - print("testing stack issues when calling finalizers") - - local X - local obj - - local function initobj () - X = false - obj = setmetatable({}, {__gc = function () X = true end}) - end - - local function loop (n) - if n > 0 then loop(n - 1) end - end - - -- should not try to call finalizer without a CallInfo available - initobj() - loop(20) -- ensure stack space - T.resetCI() -- remove extra CallInfos - T.alloccount(0) -- cannot allocate more CallInfos - obj = nil - collectgarbage() -- will not call finalizer - T.alloccount() - assert(X == false) - collectgarbage() -- now will call finalizer (it was still pending) - assert(X == true) - - -- should not try to call finalizer without stack space available - initobj() - loop(5) -- ensure enough CallInfos - T.reallocstack(0) -- remove extra stack slots - T.alloccount(0) -- cannot reallocate stack - obj = nil - collectgarbage() -- will not call finalizer - T.alloccount() - assert(X == false) - collectgarbage() -- now will call finalizer (it was still pending) - assert(X == true) -end - - print('OK') diff --git a/testes/gengc.lua b/testes/gengc.lua index 84c1a8ee..6509e39d 100644 --- a/testes/gengc.lua +++ b/testes/gengc.lua @@ -162,51 +162,6 @@ end assert(collectgarbage'isrunning') -do - -- bug in 5.0: when computing whether it should return from gen-major - -- to gen-minor, the difference between the total memory and the - -- previous total memory can be negative, which results in that - -- negative value being left-shifted (UB) - - local lim = 1e6 - - -- make major collections non-incremental - local oldsm = collectgarbage("param", "stepmul", 0) - - -- make "majorminor" large enough to force a left-shift - -- when applying the parameter (internal details) - local oldmm = collectgarbage("param", "majorminor", 2000) - - collectgarbage(); collectgarbage() - assert(not T or T.gcquery() == "genminor") - - local M = collectgarbage"count" * 1024 - - -- create a large table - local t = {} - for i = 1, lim do t[i] = true end - assert(collectgarbage"count" * 1024 > M + lim * string.packsize"j") - - -- force collector to "generational major" mode, doing several - -- minor collections that recover no memory - collectgarbage"step"; collectgarbage"step"; collectgarbage"step" - assert(not T or T.gcquery() == "genmajor") - - -- shrink the table - for i = 1, lim do t[i] = nil end - t[2 * lim] = true - assert(collectgarbage"count" < M * 5/4) - - -- bug was here, an assert violation when checking whether to - -- return to 'genminor' - collectgarbage"step" - - -- restore previous parameters - collectgarbage("param", "stepmul", oldsm) - collectgarbage("param", "majorminor", oldmm) -end - - do print"testing stop-the-world collection" local step = collectgarbage("param", "stepsize", 0); collectgarbage("incremental") diff --git a/testes/locals.lua b/testes/locals.lua index e9718341..6cd10547 100644 --- a/testes/locals.lua +++ b/testes/locals.lua @@ -1179,25 +1179,6 @@ if rawget(_G, "T") then end -do - -- detail in scopes of variables in the loop of 'repeat-until' - local res = {} - local function foo (a) - repeat - local x - local i = setmetatable({}, {__close = function () - res[#res + 1] = debug.getlocal(2, 2) -- get 'x' - res[#res + 1] = debug.getlocal(2, 3) -- get 'i' - a = true - end}) - until a - end - foo(false) - -- loop variables still in scope when closing 'i', both when 'repeat' - -- repeats and when 'repeat' stops. - assert(res[1] == "x" and res[2] == "i" and res[3] == "x" and res[4] == "i") -end - -- to-be-closed variables in generic for loops do diff --git a/testes/main.lua b/testes/main.lua index 98d36951..dc48dc48 100644 --- a/testes/main.lua +++ b/testes/main.lua @@ -78,9 +78,6 @@ end RUN('lua -v') -RUN('lua -v > %s', out) -local release = string.match(getoutput(), "Lua (%d+%.%d+%.%d+)") - print(string.format("(temporary program file used in these tests: %s)", prog)) -- running stdin as a file @@ -170,9 +167,7 @@ checkout("10\n11\n") -- test errors in LUA_INIT NoRun('LUA_INIT:1: msg', 'env LUA_INIT="error(\'msg\')" lua') - -print("testing option '-E'") - +-- test option '-E' local defaultpath, defaultCpath do @@ -197,22 +192,6 @@ assert(not string.find(defaultpath, "xxx") and string.find(defaultCpath, "lua")) --- (LUA_READLINELIB was introduced in 5.5.1) -if release >= "5.5.1" then - print"testing readline library name" - -- should generate a warning when trying to load inexistent library "xuxu" - local env = [[LUA_READLINELIB=xuxu LUA_INIT="warn('@allow')"]] - local code = 'echo " " | env %s lua %s -W -i >%s 2>&1' - RUN(code, env, "", out) -- run code with no extra options - assert(string.find(getoutput(), - "warning: unable to load readline library 'xuxu'")) - - RUN(code, env, "-E", out) -- run again with option -E - -- no warning when LUA_READLINELIB is to be ignored - assert(not string.find(getoutput(), "warning")) -end - - -- test replacement of ';;' to default path local function convert (p) prepfile("print(package.path)") diff --git a/testes/memerr.lua b/testes/memerr.lua index a55514a9..9c940ca7 100644 --- a/testes/memerr.lua +++ b/testes/memerr.lua @@ -282,25 +282,6 @@ testamem("growing stack", function () return foo(100) end) - -collectgarbage() -collectgarbage() -global io, T, setmetatable, collectgarbage, print - -local Count = 0 -testamem("finalizers", function () - local X = false - local obj = setmetatable({}, {__gc = function () X = true end}) - obj = nil - T.resetCI() -- remove extra CallInfos - T.reallocstack(18) -- remove extra stack slots - Count = Count + 1 - io.stderr:write(Count, "\n") - T.trick(io) - collectgarbage() - return X -end) - -- }================================================================== diff --git a/testes/pm.lua b/testes/pm.lua index feab33db..720d2a35 100644 --- a/testes/pm.lua +++ b/testes/pm.lua @@ -347,16 +347,6 @@ do -- init parameter in gmatch end -do -- bug since 5.3 - local N = 20000 - local iter = string.gmatch(string.rep("a", N), string.rep("a?", N)) - pcall(iter) -- error for pattern too complex - -- calling function again found recursion count ('matchdepth') equal - -- to -1, so it did not detect next C-stack overflow - pcall(iter) -end - - -- tests for `%f' (`frontiers') assert(string.gsub("aaa aa a aaa a", "%f[%w]a", "x") == "xaa xa x xaa x") diff --git a/testes/sort.lua b/testes/sort.lua index 92aaca3c..b0127660 100644 --- a/testes/sort.lua +++ b/testes/sort.lua @@ -72,19 +72,6 @@ assert(a==1 and x==nil) a,x = unpack({1,2}, 1, 1) assert(a==1 and x==nil) - -do -- unpack with non-tables - local debug = require"debug" - local oldmt = debug.getmetatable(0) - local str = "hello" - debug.setmetatable(0, - { __len = function () return #str end, - __index = function (_, i) return string.sub(str, i, i) end}) - assert(table.concat({table.unpack(0)}) == str) - debug.setmetatable(0, oldmt) -- restore original metatable for numbers -end - - do local maxi = (1 << 31) - 1 -- maximum value for an int (usually) local mini = -(1 << 31) -- minimum value for an int (usually) diff --git a/testes/tracegc.lua b/testes/tracegc.lua index c1154f90..a8c929df 100644 --- a/testes/tracegc.lua +++ b/testes/tracegc.lua @@ -1,15 +1,10 @@ -- track collections - local M = {} -- import list -local stderr, collectgarbage = io.stderr, collectgarbage - --- the debug version of setmetatable does not create any object (such as --- a '__metatable' string), and so it is more appropriate to be used in --- a finalizer -local setmetatable = require"debug".setmetatable +local setmetatable, stderr, collectgarbage = + setmetatable, io.stderr, collectgarbage global none diff --git a/testes/utf8.lua b/testes/utf8.lua index 8a0213d6..028995a4 100644 --- a/testes/utf8.lua +++ b/testes/utf8.lua @@ -238,18 +238,10 @@ s = "\0 \x7F\z s = string.gsub(s, " ", "") check(s, {0,0x7F, 0x80,0x7FF, 0x800,0xFFFF, 0x10000,0x10FFFF}) - --- again, without strictness -s = "\xF0\x90\x80\x80 \xF7\xBF\xBF\xBF\z - \xF8\x88\x80\x80\x80 \xFB\xBF\xBF\xBF\xBF\z - \xFC\x84\x80\x80\x80\x80 \xFD\xBF\xBF\xBF\xBF\xBF" -s = string.gsub(s, " ", "") -check(s, {0x10000,0x1FFFFF, 0x200000,0x3FFFFFF, 0x4000000,0x7FFFFFFF}, true) - do -- original UTF-8 values local s = "\u{4000000}\u{7FFFFFFF}" - assert(s == "\xFC\x84\x80\x80\x80\x80\xFD\xBF\xBF\xBF\xBF\xBF") + assert(#s == 12) check(s, {0x4000000, 0x7FFFFFFF}, true) s = "\u{200000}\u{3FFFFFF}" @@ -265,10 +257,6 @@ local x = "日本語a-4\0éó" check(x, {26085, 26412, 35486, 97, 45, 52, 0, 233, 243}) --- more than 5 continuation bytes -assert(not utf8.len("\xff\x8f\x8f\x8f\x8f\x8f\x8f\x8f")) - - -- Supplementary Characters check("𣲷𠜎𠱓𡁻𠵼ab𠺢", {0x23CB7, 0x2070E, 0x20C53, 0x2107B, 0x20D7C, 0x61, 0x62, 0x20EA2,})