From 6eb53b752617fae9e1329bfe2cfecdcbb593c398 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 27 Feb 2020 12:59:22 -0300 Subject: [PATCH] Details Several details in code (e.g., moving a variable to the most inner scope that encloses its uses), comments, parameter names, extra tests. --- lauxlib.c | 2 +- lcode.c | 15 +++++---------- lcode.h | 2 +- ldblib.c | 4 ++-- ldebug.c | 6 +++--- lmathlib.c | 28 +++++++++++++++------------- ltests.c | 12 +++++++----- ltests.h | 3 --- lvm.c | 13 +++++++------ testes/db.lua | 5 +++++ testes/events.lua | 1 + testes/math.lua | 4 ++++ testes/nextvar.lua | 2 +- 13 files changed, 52 insertions(+), 45 deletions(-) diff --git a/lauxlib.c b/lauxlib.c index b6740b17..72359094 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -902,10 +902,10 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { luaL_checkstack(L, nup, "too many upvalues"); for (; l->name != NULL; l++) { /* fill the table with given functions */ - int i; if (l->func == NULL) /* place holder? */ lua_pushboolean(L, 0); else { + int i; for (i = 0; i < nup; i++) /* copy upvalues to the top */ lua_pushvalue(L, -nup); lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ diff --git a/lcode.c b/lcode.c index 35e0527f..83a6d064 100644 --- a/lcode.c +++ b/lcode.c @@ -1730,17 +1730,12 @@ void luaK_fixline (FuncState *fs, int line) { } -void luaK_settablesize (FuncState *fs, int pc, int ra, int rc, int rb) { +void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { Instruction *inst = &fs->f->code[pc]; - int extra = 0; - int k = 0; - if (rb != 0) - rb = luaO_ceillog2(rb) + 1; /* hash size */ - if (rc > MAXARG_C) { /* does it need the extra argument? */ - extra = rc / (MAXARG_C + 1); - rc %= (MAXARG_C + 1); - k = 1; - } + int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0; /* hash size */ + int extra = asize / (MAXARG_C + 1); /* higher bits of array size */ + int rc = asize % (MAXARG_C + 1); /* lower bits of array size */ + int k = (extra > 0); /* true iff needs extra argument */ *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); } diff --git a/lcode.h b/lcode.h index 49c913ab..32658244 100644 --- a/lcode.h +++ b/lcode.h @@ -95,7 +95,7 @@ LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2, int line); LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, - int ra, int rb, int rc); + int ra, int asize, int hsize); LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); LUAI_FUNC void luaK_finish (FuncState *fs); LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); diff --git a/ldblib.c b/ldblib.c index 77018986..745cfd27 100644 --- a/ldblib.c +++ b/ldblib.c @@ -202,8 +202,6 @@ static int db_getinfo (lua_State *L) { static int db_getlocal (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - const char *name; int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */ if (lua_isfunction(L, arg + 1)) { /* function argument? */ lua_pushvalue(L, arg + 1); /* push function */ @@ -211,6 +209,8 @@ static int db_getlocal (lua_State *L) { return 1; /* return only name (there is no value) */ } else { /* stack-level argument */ + lua_Debug ar; + const char *name; int level = (int)luaL_checkinteger(L, arg + 1); if (!lua_getstack(L1, level, &ar)) /* out of range? */ return luaL_argerror(L, arg+1, "level out of range"); diff --git a/ldebug.c b/ldebug.c index a1913c59..eaac16f7 100644 --- a/ldebug.c +++ b/ldebug.c @@ -101,7 +101,7 @@ int luaG_getfuncline (const Proto *f, int pc) { } -static int currentline (CallInfo *ci) { +static int getcurrentline (CallInfo *ci) { return luaG_getfuncline(ci_func(ci)->p, currentpc(ci)); } @@ -339,7 +339,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, break; } case 'l': { - ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; + ar->currentline = (ci && isLua(ci)) ? getcurrentline(ci) : -1; break; } case 'u': { @@ -775,7 +775,7 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { msg = luaO_pushvfstring(L, fmt, argp); /* format message */ va_end(argp); if (isLua(ci)) /* if Lua function, add source:line information */ - luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci)); + luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci)); luaG_errormsg(L); } diff --git a/lmathlib.c b/lmathlib.c index 7197fc59..63f6036a 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -522,16 +522,18 @@ typedef struct { ** Project the random integer 'ran' into the interval [0, n]. ** Because 'ran' has 2^B possible values, the projection can only be ** uniform when the size of the interval is a power of 2 (exact -** division). To get a uniform projection into [0, n], we first compute -** 'lim', the smallest Mersenne number not smaller than 'n'. We then -** project 'ran' into the interval [0, lim]. If the result is inside -** [0, n], we are done. Otherwise, we try with another 'ran', until we -** have a result inside the interval. +** division). Otherwise, to get a uniform projection into [0, n], we +** first compute 'lim', the smallest Mersenne number not smaller than +** 'n'. We then project 'ran' into the interval [0, lim]. If the result +** is inside [0, n], we are done. Otherwise, we try with another 'ran', +** until we have a result inside the interval. */ static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, RanState *state) { - lua_Unsigned lim = n; - if ((lim & (lim + 1)) > 0) { /* 'lim + 1' is not a power of 2? */ + if ((n & (n + 1)) == 0) /* is 'n + 1' a power of 2? */ + return ran & n; /* no bias */ + else { + lua_Unsigned lim = n; /* compute the smallest (2^b - 1) not smaller than 'n' */ lim |= (lim >> 1); lim |= (lim >> 2); @@ -541,13 +543,13 @@ static lua_Unsigned project (lua_Unsigned ran, lua_Unsigned n, #if (LUA_MAXUNSIGNED >> 31) >= 3 lim |= (lim >> 32); /* integer type has more than 32 bits */ #endif + lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ + && lim >= n /* not smaller than 'n', */ + && (lim >> 1) < n); /* and it is the smallest one */ + while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ + ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ + return ran; } - lua_assert((lim & (lim + 1)) == 0 /* 'lim + 1' is a power of 2, */ - && lim >= n /* not smaller than 'n', */ - && (lim == 0 || (lim >> 1) < n)); /* and it is the smallest one */ - while ((ran &= lim) > n) /* project 'ran' into [0..lim] */ - ran = I2UInt(nextrand(state->s)); /* not inside [0..n]? try again */ - return ran; } diff --git a/ltests.c b/ltests.c index acabc6b6..76a6ea9b 100644 --- a/ltests.c +++ b/ltests.c @@ -419,17 +419,19 @@ static void checkstack (global_State *g, lua_State *L1) { CallInfo *ci; UpVal *uv; lua_assert(!isdead(g, L1)); + if (L1->stack == NULL) { /* incomplete thread? */ + lua_assert(L1->stacksize == 0 && L1->openupval == NULL && + L1->ci == NULL); + return; + } for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) lua_assert(upisopen(uv)); /* must be open */ for (ci = L1->ci; ci != NULL; ci = ci->previous) { lua_assert(ci->top <= L1->stack_last); lua_assert(lua_checkpc(ci)); } - if (L1->stack) { /* complete thread? */ - for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) - checkliveness(L1, s2v(o)); /* entire stack must have valid values */ - } - else lua_assert(L1->stacksize == 0); + for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) + checkliveness(L1, s2v(o)); /* entire stack must have valid values */ } diff --git a/ltests.h b/ltests.h index 7328aaca..db0a2a0d 100644 --- a/ltests.h +++ b/ltests.h @@ -25,9 +25,6 @@ #define lua_assert(c) assert(c) -/* include opcode names */ -#define LUAI_DEFOPNAMES - /* compiled with -O0, Lua uses a lot of C stack space... */ #undef LUAI_MAXCSTACK diff --git a/lvm.c b/lvm.c index d802379c..e7781dbf 100644 --- a/lvm.c +++ b/lvm.c @@ -980,11 +980,11 @@ void luaV_finishOp (lua_State *L) { /* -** Order operations with register operands. 'opf' actually works +** Order operations with register operands. 'opn' actually works ** for all numbers, but the fast track improves performance for ** integers. */ -#define op_order(L,opi,opf,other) { \ +#define op_order(L,opi,opn,other) { \ int cond; \ TValue *rb = vRB(i); \ if (ttisinteger(s2v(ra)) && ttisinteger(rb)) { \ @@ -993,7 +993,7 @@ void luaV_finishOp (lua_State *L) { cond = opi(ia, ib); \ } \ else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \ - cond = opf(s2v(ra), rb); \ + cond = opn(s2v(ra), rb); \ else \ Protect(cond = other(L, s2v(ra), rb)); \ docondjump(); } @@ -1323,8 +1323,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) { Table *t; if (b > 0) b = 1 << (b - 1); /* size is 2^(b - 1) */ - if (TESTARG_k(i)) - c += GETARG_Ax(*pc) * (MAXARG_C + 1); + lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0)); + if (TESTARG_k(i)) /* non-zero extra argument? */ + c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ pc++; /* skip extra argument */ L->top = ra + 1; /* correct top in case of emergency GC */ t = luaH_new(L); /* memory allocation */ @@ -1558,7 +1559,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { vmcase(OP_EQK) { TValue *rb = KB(i); /* basic types do not use '__eq'; we can use raw equality */ - int cond = luaV_equalobj(NULL, s2v(ra), rb); + int cond = luaV_rawequalobj(s2v(ra), rb); docondjump(); vmbreak; } diff --git a/testes/db.lua b/testes/db.lua index 074a6d0b..941283f7 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -649,6 +649,11 @@ t = debug.getinfo(1) -- main assert(t.isvararg == true and t.nparams == 0 and t.nups == 1 and debug.getupvalue(t.func, 1) == "_ENV") +t = debug.getinfo(math.sin) -- C function +assert(t.isvararg == true and t.nparams == 0 and t.nups == 0) + +t = debug.getinfo(string.gmatch("abc", "a")) -- C closure +assert(t.isvararg == true and t.nparams == 0 and t.nups > 0) diff --git a/testes/events.lua b/testes/events.lua index d0abe1d4..8a01330e 100644 --- a/testes/events.lua +++ b/testes/events.lua @@ -325,6 +325,7 @@ else assert(u1 == u3 and u3 == u1 and u1 ~= u2) assert(u2 == u1 and u2 == u3 and u3 == u2) assert(u2 ~= {}) -- different types cannot be equal + assert(rawequal(u1, u1) and not rawequal(u1, u3)) local mirror = {} debug.setmetatable(u3, {__index = mirror, __newindex = mirror}) diff --git a/testes/math.lua b/testes/math.lua index 7248787b..930221e3 100644 --- a/testes/math.lua +++ b/testes/math.lua @@ -960,7 +960,10 @@ do aux(-10,0) aux(1, 6) aux(1, 2) + aux(1, 13) + aux(1, 31) aux(1, 32) + aux(1, 33) aux(-10, 10) aux(-10,-10) -- unit set aux(minint, minint) -- unit set @@ -998,6 +1001,7 @@ do end aux(0, maxint) aux(1, maxint) + aux(3, maxint // 3) aux(minint, -1) aux(minint // 2, maxint // 2) aux(minint, maxint) diff --git a/testes/nextvar.lua b/testes/nextvar.lua index 9d919631..73af77dd 100644 --- a/testes/nextvar.lua +++ b/testes/nextvar.lua @@ -76,7 +76,7 @@ end -- testing constructor sizes local sizes = {0, 1, 2, 3, 4, 5, 7, 8, 9, 15, 16, 17, - 30, 31, 32, 33, 34, 500, 1000} + 30, 31, 32, 33, 34, 254, 255, 256, 500, 1000} for _, sa in ipairs(sizes) do -- 'sa' is size of the array part local arr = {"return {"}