From e8deac5a41ffd644aaa78fda6d4bd5caa72cb077 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 10 Nov 2021 15:07:14 -0300 Subject: [PATCH] Avoid OP_VARARGPREP for active lines when building the table 'activelines' for a vararg function, this first instruction does not make the first line active. --- ldebug.c | 9 ++++++++- testes/db.lua | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/ldebug.c b/ldebug.c index dde4669e..30a28828 100644 --- a/ldebug.c +++ b/ldebug.c @@ -301,7 +301,14 @@ static void collectvalidlines (lua_State *L, Closure *f) { sethvalue2s(L, L->top, t); /* push it on stack */ api_incr_top(L); setbtvalue(&v); /* boolean 'true' to be the value of all indices */ - for (i = 0; i < p->sizelineinfo; i++) { /* for all instructions */ + if (!p->is_vararg) /* regular function? */ + i = 0; /* consider all instructions */ + else { /* vararg function */ + lua_assert(p->code[0] == OP_VARARGPREP); + currentline = nextline(p, currentline, 0); + i = 1; /* skip first instruction (OP_VARARGPREP) */ + } + for (; i < p->sizelineinfo; i++) { /* for each instruction */ currentline = nextline(p, currentline, i); /* get its line */ luaH_setint(L, t, currentline, &v); /* table[line] = true */ } diff --git a/testes/db.lua b/testes/db.lua index d64952d9..11dfd26c 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -195,6 +195,49 @@ do -- testing line info/trace with large gaps in source end end + +do -- testing active lines + local function checkactivelines (f, lines) + local t = debug.getinfo(f, "SL") + for _, l in pairs(lines) do + l = l + t.linedefined + assert(t.activelines[l]) + t.activelines[l] = undef + end + assert(next(t.activelines) == nil) -- no extra lines + end + + checkactivelines(function (...) -- vararg function + -- 1st line is empty + -- 2nd line is empty + -- 3th line is empty + local a = 20 + -- 5th line is empty + local b = 30 + -- 7th line is empty + end, {4, 6, 8}) + + checkactivelines(function (a) + -- 1st line is empty + -- 2nd line is empty + local a = 20 + local b = 30 + -- 5th line is empty + end, {3, 4, 6}) + + checkactivelines(function (...) end, {0}) + + checkactivelines(function (a, b) + end, {1}) + + for _, n in pairs{0, 1, 2, 10, 50, 100, 1000, 10000} do + checkactivelines( + load(string.format("%s return 1", string.rep("\n", n))), + {n + 1}) + end + +end + print'+' -- invalid levels in [gs]etlocal