summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-11-10 15:07:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-11-10 15:07:14 -0300
commite8deac5a41ffd644aaa78fda6d4bd5caa72cb077 (patch)
treef4a3d2a2f24adc6d58b4088705b85e349dd2a8e5
parentbfbff3703edae789fa5efa9bf174f8e7cff4ded8 (diff)
downloadlua-github-e8deac5a41ffd644aaa78fda6d4bd5caa72cb077.tar.gz
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.
-rw-r--r--ldebug.c9
-rw-r--r--testes/db.lua43
2 files changed, 51 insertions, 1 deletions
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