diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-11-10 15:07:14 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-11-10 15:07:14 -0300 |
commit | e8deac5a41ffd644aaa78fda6d4bd5caa72cb077 (patch) | |
tree | f4a3d2a2f24adc6d58b4088705b85e349dd2a8e5 | |
parent | bfbff3703edae789fa5efa9bf174f8e7cff4ded8 (diff) | |
download | lua-e8deac5a41ffd644aaa78fda6d4bd5caa72cb077.tar.gz lua-e8deac5a41ffd644aaa78fda6d4bd5caa72cb077.tar.bz2 lua-e8deac5a41ffd644aaa78fda6d4bd5caa72cb077.zip |
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.c | 9 | ||||
-rw-r--r-- | testes/db.lua | 43 |
2 files changed, 51 insertions, 1 deletions
@@ -301,7 +301,14 @@ static void collectvalidlines (lua_State *L, Closure *f) { | |||
301 | sethvalue2s(L, L->top, t); /* push it on stack */ | 301 | sethvalue2s(L, L->top, t); /* push it on stack */ |
302 | api_incr_top(L); | 302 | api_incr_top(L); |
303 | setbtvalue(&v); /* boolean 'true' to be the value of all indices */ | 303 | setbtvalue(&v); /* boolean 'true' to be the value of all indices */ |
304 | for (i = 0; i < p->sizelineinfo; i++) { /* for all instructions */ | 304 | if (!p->is_vararg) /* regular function? */ |
305 | i = 0; /* consider all instructions */ | ||
306 | else { /* vararg function */ | ||
307 | lua_assert(p->code[0] == OP_VARARGPREP); | ||
308 | currentline = nextline(p, currentline, 0); | ||
309 | i = 1; /* skip first instruction (OP_VARARGPREP) */ | ||
310 | } | ||
311 | for (; i < p->sizelineinfo; i++) { /* for each instruction */ | ||
305 | currentline = nextline(p, currentline, i); /* get its line */ | 312 | currentline = nextline(p, currentline, i); /* get its line */ |
306 | luaH_setint(L, t, currentline, &v); /* table[line] = true */ | 313 | luaH_setint(L, t, currentline, &v); /* table[line] = true */ |
307 | } | 314 | } |
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 | |||
195 | end | 195 | end |
196 | end | 196 | end |
197 | 197 | ||
198 | |||
199 | do -- testing active lines | ||
200 | local function checkactivelines (f, lines) | ||
201 | local t = debug.getinfo(f, "SL") | ||
202 | for _, l in pairs(lines) do | ||
203 | l = l + t.linedefined | ||
204 | assert(t.activelines[l]) | ||
205 | t.activelines[l] = undef | ||
206 | end | ||
207 | assert(next(t.activelines) == nil) -- no extra lines | ||
208 | end | ||
209 | |||
210 | checkactivelines(function (...) -- vararg function | ||
211 | -- 1st line is empty | ||
212 | -- 2nd line is empty | ||
213 | -- 3th line is empty | ||
214 | local a = 20 | ||
215 | -- 5th line is empty | ||
216 | local b = 30 | ||
217 | -- 7th line is empty | ||
218 | end, {4, 6, 8}) | ||
219 | |||
220 | checkactivelines(function (a) | ||
221 | -- 1st line is empty | ||
222 | -- 2nd line is empty | ||
223 | local a = 20 | ||
224 | local b = 30 | ||
225 | -- 5th line is empty | ||
226 | end, {3, 4, 6}) | ||
227 | |||
228 | checkactivelines(function (...) end, {0}) | ||
229 | |||
230 | checkactivelines(function (a, b) | ||
231 | end, {1}) | ||
232 | |||
233 | for _, n in pairs{0, 1, 2, 10, 50, 100, 1000, 10000} do | ||
234 | checkactivelines( | ||
235 | load(string.format("%s return 1", string.rep("\n", n))), | ||
236 | {n + 1}) | ||
237 | end | ||
238 | |||
239 | end | ||
240 | |||
198 | print'+' | 241 | print'+' |
199 | 242 | ||
200 | -- invalid levels in [gs]etlocal | 243 | -- invalid levels in [gs]etlocal |