summaryrefslogtreecommitdiff
path: root/testes/db.lua
diff options
context:
space:
mode:
Diffstat (limited to 'testes/db.lua')
-rw-r--r--testes/db.lua857
1 files changed, 857 insertions, 0 deletions
diff --git a/testes/db.lua b/testes/db.lua
new file mode 100644
index 00000000..004f57a7
--- /dev/null
+++ b/testes/db.lua
@@ -0,0 +1,857 @@
1-- $Id: db.lua,v 1.79 2016/11/07 13:02:34 roberto Exp $
2-- See Copyright Notice in file all.lua
3
4-- testing debug library
5
6local debug = require "debug"
7
8local function dostring(s) return assert(load(s))() end
9
10print"testing debug library and debug information"
11
12do
13local a=1
14end
15
16assert(not debug.gethook())
17
18local testline = 19 -- line where 'test' is defined
19function test (s, l, p) -- this must be line 19
20 collectgarbage() -- avoid gc during trace
21 local function f (event, line)
22 assert(event == 'line')
23 local l = table.remove(l, 1)
24 if p then print(l, line) end
25 assert(l == line, "wrong trace!!")
26 end
27 debug.sethook(f,"l"); load(s)(); debug.sethook()
28 assert(#l == 0)
29end
30
31
32do
33 assert(not pcall(debug.getinfo, print, "X")) -- invalid option
34 assert(not debug.getinfo(1000)) -- out of range level
35 assert(not debug.getinfo(-1)) -- out of range level
36 local a = debug.getinfo(print)
37 assert(a.what == "C" and a.short_src == "[C]")
38 a = debug.getinfo(print, "L")
39 assert(a.activelines == nil)
40 local b = debug.getinfo(test, "SfL")
41 assert(b.name == nil and b.what == "Lua" and b.linedefined == testline and
42 b.lastlinedefined == b.linedefined + 10 and
43 b.func == test and not string.find(b.short_src, "%["))
44 assert(b.activelines[b.linedefined + 1] and
45 b.activelines[b.lastlinedefined])
46 assert(not b.activelines[b.linedefined] and
47 not b.activelines[b.lastlinedefined + 1])
48end
49
50
51-- test file and string names truncation
52a = "function f () end"
53local function dostring (s, x) return load(s, x)() end
54dostring(a)
55assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a))
56dostring(a..string.format("; %s\n=1", string.rep('p', 400)))
57assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$'))
58dostring(a..string.format("; %s=1", string.rep('p', 400)))
59assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$'))
60dostring("\n"..a)
61assert(debug.getinfo(f).short_src == '[string "..."]')
62dostring(a, "")
63assert(debug.getinfo(f).short_src == '[string ""]')
64dostring(a, "@xuxu")
65assert(debug.getinfo(f).short_src == "xuxu")
66dostring(a, "@"..string.rep('p', 1000)..'t')
67assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$"))
68dostring(a, "=xuxu")
69assert(debug.getinfo(f).short_src == "xuxu")
70dostring(a, string.format("=%s", string.rep('x', 500)))
71assert(string.find(debug.getinfo(f).short_src, "^x*$"))
72dostring(a, "=")
73assert(debug.getinfo(f).short_src == "")
74a = nil; f = nil;
75
76
77repeat
78 local g = {x = function ()
79 local a = debug.getinfo(2)
80 assert(a.name == 'f' and a.namewhat == 'local')
81 a = debug.getinfo(1)
82 assert(a.name == 'x' and a.namewhat == 'field')
83 return 'xixi'
84 end}
85 local f = function () return 1+1 and (not 1 or g.x()) end
86 assert(f() == 'xixi')
87 g = debug.getinfo(f)
88 assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name)
89
90 function f (x, name) -- local!
91 name = name or 'f'
92 local a = debug.getinfo(1)
93 assert(a.name == name and a.namewhat == 'local')
94 return x
95 end
96
97 -- breaks in different conditions
98 if 3>4 then break end; f()
99 if 3<4 then a=1 else break end; f()
100 while 1 do local x=10; break end; f()
101 local b = 1
102 if 3>4 then return math.sin(1) end; f()
103 a = 3<4; f()
104 a = 3<4 or 1; f()
105 repeat local x=20; if 4>3 then f() else break end; f() until 1
106 g = {}
107 f(g).x = f(2) and f(10)+f(9)
108 assert(g.x == f(19))
109 function g(x) if not x then return 3 end return (x('a', 'x')) end
110 assert(g(f) == 'a')
111until 1
112
113test([[if
114math.sin(1)
115then
116 a=1
117else
118 a=2
119end
120]], {2,3,4,7})
121
122test([[--
123if nil then
124 a=1
125else
126 a=2
127end
128]], {2,5,6})
129
130test([[a=1
131repeat
132 a=a+1
133until a==3
134]], {1,3,4,3,4})
135
136test([[ do
137 return
138end
139]], {2})
140
141test([[local a
142a=1
143while a<=3 do
144 a=a+1
145end
146]], {1,2,3,4,3,4,3,4,3,5})
147
148test([[while math.sin(1) do
149 if math.sin(1)
150 then break
151 end
152end
153a=1]], {1,2,3,6})
154
155test([[for i=1,3 do
156 a=i
157end
158]], {1,2,1,2,1,2,1,3})
159
160test([[for i,v in pairs{'a','b'} do
161 a=tostring(i) .. v
162end
163]], {1,2,1,2,1,3})
164
165test([[for i=1,4 do a=1 end]], {1,1,1,1,1})
166
167
168
169print'+'
170
171-- invalid levels in [gs]etlocal
172assert(not pcall(debug.getlocal, 20, 1))
173assert(not pcall(debug.setlocal, -1, 1, 10))
174
175
176-- parameter names
177local function foo (a,b,...) local d, e end
178local co = coroutine.create(foo)
179
180assert(debug.getlocal(foo, 1) == 'a')
181assert(debug.getlocal(foo, 2) == 'b')
182assert(not debug.getlocal(foo, 3))
183assert(debug.getlocal(co, foo, 1) == 'a')
184assert(debug.getlocal(co, foo, 2) == 'b')
185assert(not debug.getlocal(co, foo, 3))
186
187assert(not debug.getlocal(print, 1))
188
189
190-- varargs
191local function foo (a, ...)
192 local t = table.pack(...)
193 for i = 1, t.n do
194 local n, v = debug.getlocal(1, -i)
195 assert(n == "(*vararg)" and v == t[i])
196 end
197 assert(not debug.getlocal(1, -(t.n + 1)))
198 assert(not debug.setlocal(1, -(t.n + 1), 30))
199 if t.n > 0 then
200 (function (x)
201 assert(debug.setlocal(2, -1, x) == "(*vararg)")
202 assert(debug.setlocal(2, -t.n, x) == "(*vararg)")
203 end)(430)
204 assert(... == 430)
205 end
206end
207
208foo()
209foo(print)
210foo(200, 3, 4)
211local a = {}
212for i = 1, (_soft and 100 or 1000) do a[i] = i end
213foo(table.unpack(a))
214a = nil
215
216-- access to vararg in non-vararg function
217local function foo () return debug.getlocal(1, -1) end
218assert(not foo(10))
219
220
221do -- test hook presence in debug info
222 assert(not debug.gethook())
223 local count = 0
224 local function f ()
225 assert(debug.getinfo(1).namewhat == "hook")
226 local sndline = string.match(debug.traceback(), "\n(.-)\n")
227 assert(string.find(sndline, "hook"))
228 count = count + 1
229 end
230 debug.sethook(f, "l")
231 local a = 0
232 _ENV.a = a
233 a = 1
234 debug.sethook()
235 assert(count == 4)
236end
237
238
239a = {}; L = nil
240local glob = 1
241local oldglob = glob
242debug.sethook(function (e,l)
243 collectgarbage() -- force GC during a hook
244 local f, m, c = debug.gethook()
245 assert(m == 'crl' and c == 0)
246 if e == "line" then
247 if glob ~= oldglob then
248 L = l-1 -- get the first line where "glob" has changed
249 oldglob = glob
250 end
251 elseif e == "call" then
252 local f = debug.getinfo(2, "f").func
253 a[f] = 1
254 else assert(e == "return")
255 end
256end, "crl")
257
258
259function f(a,b)
260 collectgarbage()
261 local _, x = debug.getlocal(1, 1)
262 local _, y = debug.getlocal(1, 2)
263 assert(x == a and y == b)
264 assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
265 assert(debug.setlocal(2, 4, "maçã") == "B")
266 x = debug.getinfo(2)
267 assert(x.func == g and x.what == "Lua" and x.name == 'g' and
268 x.nups == 2 and string.find(x.source, "^@.*db%.lua$"))
269 glob = glob+1
270 assert(debug.getinfo(1, "l").currentline == L+1)
271 assert(debug.getinfo(1, "l").currentline == L+2)
272end
273
274function foo()
275 glob = glob+1
276 assert(debug.getinfo(1, "l").currentline == L+1)
277end; foo() -- set L
278-- check line counting inside strings and empty lines
279
280_ = 'alo\
281alo' .. [[
282
283]]
284--[[
285]]
286assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines
287
288
289function g(...)
290 local arg = {...}
291 do local a,b,c; a=math.sin(40); end
292 local feijao
293 local AAAA,B = "xuxu", "mamão"
294 f(AAAA,B)
295 assert(AAAA == "pera" and B == "maçã")
296 do
297 local B = 13
298 local x,y = debug.getlocal(1,5)
299 assert(x == 'B' and y == 13)
300 end
301end
302
303g()
304
305
306assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print])
307
308
309-- tests for manipulating non-registered locals (C and Lua temporaries)
310
311local n, v = debug.getlocal(0, 1)
312assert(v == 0 and n == "(*temporary)")
313local n, v = debug.getlocal(0, 2)
314assert(v == 2 and n == "(*temporary)")
315assert(not debug.getlocal(0, 3))
316assert(not debug.getlocal(0, 0))
317
318function f()
319 assert(select(2, debug.getlocal(2,3)) == 1)
320 assert(not debug.getlocal(2,4))
321 debug.setlocal(2, 3, 10)
322 return 20
323end
324
325function g(a,b) return (a+1) + f() end
326
327assert(g(0,0) == 30)
328
329
330debug.sethook(nil);
331assert(debug.gethook() == nil)
332
333
334-- testing access to function arguments
335
336local function collectlocals (level)
337 local tab = {}
338 for i = 1, math.huge do
339 local n, v = debug.getlocal(level + 1, i)
340 if not (n and string.find(n, "^[a-zA-Z0-9_]+$")) then
341 break -- consider only real variables
342 end
343 tab[n] = v
344 end
345 return tab
346end
347
348
349X = nil
350a = {}
351function a:f (a, b, ...) local arg = {...}; local c = 13 end
352debug.sethook(function (e)
353 assert(e == "call")
354 dostring("XX = 12") -- test dostring inside hooks
355 -- testing errors inside hooks
356 assert(not pcall(load("a='joao'+1")))
357 debug.sethook(function (e, l)
358 assert(debug.getinfo(2, "l").currentline == l)
359 local f,m,c = debug.gethook()
360 assert(e == "line")
361 assert(m == 'l' and c == 0)
362 debug.sethook(nil) -- hook is called only once
363 assert(not X) -- check that
364 X = collectlocals(2)
365 end, "l")
366end, "c")
367
368a:f(1,2,3,4,5)
369assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil)
370assert(XX == 12)
371assert(debug.gethook() == nil)
372
373
374-- testing access to local variables in return hook (bug in 5.2)
375do
376 local function foo (a, b)
377 do local x,y,z end
378 local c, d = 10, 20
379 return
380 end
381
382 local function aux ()
383 if debug.getinfo(2).name == "foo" then
384 foo = nil -- to signal that it found 'foo'
385 local tab = {a = 100, b = 200, c = 10, d = 20}
386 for n, v in pairs(collectlocals(2)) do
387 assert(tab[n] == v)
388 tab[n] = nil
389 end
390 assert(next(tab) == nil) -- 'tab' must be empty
391 end
392 end
393
394 debug.sethook(aux, "r"); foo(100, 200); debug.sethook()
395 assert(foo == nil)
396end
397
398-- testing upvalue access
399local function getupvalues (f)
400 local t = {}
401 local i = 1
402 while true do
403 local name, value = debug.getupvalue(f, i)
404 if not name then break end
405 assert(not t[name])
406 t[name] = value
407 i = i + 1
408 end
409 return t
410end
411
412local a,b,c = 1,2,3
413local function foo1 (a) b = a; return c end
414local function foo2 (x) a = x; return c+b end
415assert(not debug.getupvalue(foo1, 3))
416assert(not debug.getupvalue(foo1, 0))
417assert(not debug.setupvalue(foo1, 3, "xuxu"))
418local t = getupvalues(foo1)
419assert(t.a == nil and t.b == 2 and t.c == 3)
420t = getupvalues(foo2)
421assert(t.a == 1 and t.b == 2 and t.c == 3)
422assert(debug.setupvalue(foo1, 1, "xuxu") == "b")
423assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu")
424-- upvalues of C functions are allways "called" "" (the empty string)
425assert(debug.getupvalue(string.gmatch("x", "x"), 1) == "")
426
427
428-- testing count hooks
429local a=0
430debug.sethook(function (e) a=a+1 end, "", 1)
431a=0; for i=1,1000 do end; assert(1000 < a and a < 1012)
432debug.sethook(function (e) a=a+1 end, "", 4)
433a=0; for i=1,1000 do end; assert(250 < a and a < 255)
434local f,m,c = debug.gethook()
435assert(m == "" and c == 4)
436debug.sethook(function (e) a=a+1 end, "", 4000)
437a=0; for i=1,1000 do end; assert(a == 0)
438
439do
440 debug.sethook(print, "", 2^24 - 1) -- count upperbound
441 local f,m,c = debug.gethook()
442 assert(({debug.gethook()})[3] == 2^24 - 1)
443end
444
445debug.sethook()
446
447
448-- tests for tail calls
449local function f (x)
450 if x then
451 assert(debug.getinfo(1, "S").what == "Lua")
452 assert(debug.getinfo(1, "t").istailcall == true)
453 local tail = debug.getinfo(2)
454 assert(tail.func == g1 and tail.istailcall == true)
455 assert(debug.getinfo(3, "S").what == "main")
456 print"+"
457 end
458end
459
460function g(x) return f(x) end
461
462function g1(x) g(x) end
463
464local function h (x) local f=g1; return f(x) end
465
466h(true)
467
468local b = {}
469debug.sethook(function (e) table.insert(b, e) end, "cr")
470h(false)
471debug.sethook()
472local res = {"return", -- first return (from sethook)
473 "call", "tail call", "call", "tail call",
474 "return", "return",
475 "call", -- last call (to sethook)
476}
477for i = 1, #res do assert(res[i] == table.remove(b, 1)) end
478
479b = 0
480debug.sethook(function (e)
481 if e == "tail call" then
482 b = b + 1
483 assert(debug.getinfo(2, "t").istailcall == true)
484 else
485 assert(debug.getinfo(2, "t").istailcall == false)
486 end
487 end, "c")
488h(false)
489debug.sethook()
490assert(b == 2) -- two tail calls
491
492lim = _soft and 3000 or 30000
493local function foo (x)
494 if x==0 then
495 assert(debug.getinfo(2).what == "main")
496 local info = debug.getinfo(1)
497 assert(info.istailcall == true and info.func == foo)
498 else return foo(x-1)
499 end
500end
501
502foo(lim)
503
504
505print"+"
506
507
508-- testing local function information
509co = load[[
510 local A = function ()
511 return x
512 end
513 return
514]]
515
516local a = 0
517-- 'A' should be visible to debugger only after its complete definition
518debug.sethook(function (e, l)
519 if l == 3 then a = a + 1; assert(debug.getlocal(2, 1) == "(*temporary)")
520 elseif l == 4 then a = a + 1; assert(debug.getlocal(2, 1) == "A")
521 end
522end, "l")
523co() -- run local function definition
524debug.sethook() -- turn off hook
525assert(a == 2) -- ensure all two lines where hooked
526
527-- testing traceback
528
529assert(debug.traceback(print) == print)
530assert(debug.traceback(print, 4) == print)
531assert(string.find(debug.traceback("hi", 4), "^hi\n"))
532assert(string.find(debug.traceback("hi"), "^hi\n"))
533assert(not string.find(debug.traceback("hi"), "'debug.traceback'"))
534assert(string.find(debug.traceback("hi", 0), "'debug.traceback'"))
535assert(string.find(debug.traceback(), "^stack traceback:\n"))
536
537do -- C-function names in traceback
538 local st, msg = (function () return pcall end)()(debug.traceback)
539 assert(st == true and string.find(msg, "pcall"))
540end
541
542
543-- testing nparams, nups e isvararg
544local t = debug.getinfo(print, "u")
545assert(t.isvararg == true and t.nparams == 0 and t.nups == 0)
546
547t = debug.getinfo(function (a,b,c) end, "u")
548assert(t.isvararg == false and t.nparams == 3 and t.nups == 0)
549
550t = debug.getinfo(function (a,b,...) return t[a] end, "u")
551assert(t.isvararg == true and t.nparams == 2 and t.nups == 1)
552
553t = debug.getinfo(1) -- main
554assert(t.isvararg == true and t.nparams == 0 and t.nups == 1 and
555 debug.getupvalue(t.func, 1) == "_ENV")
556
557
558
559
560-- testing debugging of coroutines
561
562local function checktraceback (co, p, level)
563 local tb = debug.traceback(co, nil, level)
564 local i = 0
565 for l in string.gmatch(tb, "[^\n]+\n?") do
566 assert(i == 0 or string.find(l, p[i]))
567 i = i+1
568 end
569 assert(p[i] == nil)
570end
571
572
573local function f (n)
574 if n > 0 then f(n-1)
575 else coroutine.yield() end
576end
577
578local co = coroutine.create(f)
579coroutine.resume(co, 3)
580checktraceback(co, {"yield", "db.lua", "db.lua", "db.lua", "db.lua"})
581checktraceback(co, {"db.lua", "db.lua", "db.lua", "db.lua"}, 1)
582checktraceback(co, {"db.lua", "db.lua", "db.lua"}, 2)
583checktraceback(co, {"db.lua"}, 4)
584checktraceback(co, {}, 40)
585
586
587co = coroutine.create(function (x)
588 local a = 1
589 coroutine.yield(debug.getinfo(1, "l"))
590 coroutine.yield(debug.getinfo(1, "l").currentline)
591 return a
592 end)
593
594local tr = {}
595local foo = function (e, l) if l then table.insert(tr, l) end end
596debug.sethook(co, foo, "lcr")
597
598local _, l = coroutine.resume(co, 10)
599local x = debug.getinfo(co, 1, "lfLS")
600assert(x.currentline == l.currentline and x.activelines[x.currentline])
601assert(type(x.func) == "function")
602for i=x.linedefined + 1, x.lastlinedefined do
603 assert(x.activelines[i])
604 x.activelines[i] = nil
605end
606assert(next(x.activelines) == nil) -- no 'extra' elements
607assert(not debug.getinfo(co, 2))
608local a,b = debug.getlocal(co, 1, 1)
609assert(a == "x" and b == 10)
610a,b = debug.getlocal(co, 1, 2)
611assert(a == "a" and b == 1)
612debug.setlocal(co, 1, 2, "hi")
613assert(debug.gethook(co) == foo)
614assert(#tr == 2 and
615 tr[1] == l.currentline-1 and tr[2] == l.currentline)
616
617a,b,c = pcall(coroutine.resume, co)
618assert(a and b and c == l.currentline+1)
619checktraceback(co, {"yield", "in function <"})
620
621a,b = coroutine.resume(co)
622assert(a and b == "hi")
623assert(#tr == 4 and tr[4] == l.currentline+2)
624assert(debug.gethook(co) == foo)
625assert(not debug.gethook())
626checktraceback(co, {})
627
628
629-- check get/setlocal in coroutines
630co = coroutine.create(function (x)
631 local a, b = coroutine.yield(x)
632 assert(a == 100 and b == nil)
633 return x
634end)
635a, b = coroutine.resume(co, 10)
636assert(a and b == 10)
637a, b = debug.getlocal(co, 1, 1)
638assert(a == "x" and b == 10)
639assert(not debug.getlocal(co, 1, 5))
640assert(debug.setlocal(co, 1, 1, 30) == "x")
641assert(not debug.setlocal(co, 1, 5, 40))
642a, b = coroutine.resume(co, 100)
643assert(a and b == 30)
644
645
646-- check traceback of suspended (or dead with error) coroutines
647
648function f(i) if i==0 then error(i) else coroutine.yield(); f(i-1) end end
649
650co = coroutine.create(function (x) f(x) end)
651a, b = coroutine.resume(co, 3)
652t = {"'coroutine.yield'", "'f'", "in function <"}
653while coroutine.status(co) == "suspended" do
654 checktraceback(co, t)
655 a, b = coroutine.resume(co)
656 table.insert(t, 2, "'f'") -- one more recursive call to 'f'
657end
658t[1] = "'error'"
659checktraceback(co, t)
660
661
662-- test acessing line numbers of a coroutine from a resume inside
663-- a C function (this is a known bug in Lua 5.0)
664
665local function g(x)
666 coroutine.yield(x)
667end
668
669local function f (i)
670 debug.sethook(function () end, "l")
671 for j=1,1000 do
672 g(i+j)
673 end
674end
675
676local co = coroutine.wrap(f)
677co(10)
678pcall(co)
679pcall(co)
680
681
682assert(type(debug.getregistry()) == "table")
683
684
685-- test tagmethod information
686local a = {}
687local function f (t)
688 local info = debug.getinfo(1);
689 assert(info.namewhat == "metamethod")
690 a.op = info.name
691 return info.name
692end
693setmetatable(a, {
694 __index = f; __add = f; __div = f; __mod = f; __concat = f; __pow = f;
695 __mul = f; __idiv = f; __unm = f; __len = f; __sub = f;
696 __shl = f; __shr = f; __bor = f; __bxor = f;
697 __eq = f; __le = f; __lt = f; __unm = f; __len = f; __band = f;
698 __bnot = f;
699})
700
701local b = setmetatable({}, getmetatable(a))
702
703assert(a[3] == "__index" and a^3 == "__pow" and a..a == "__concat")
704assert(a/3 == "__div" and 3%a == "__mod")
705assert(a+3 == "__add" and 3-a == "__sub" and a*3 == "__mul" and
706 -a == "__unm" and #a == "__len" and a&3 == "__band")
707assert(a|3 == "__bor" and 3~a == "__bxor" and a<<3 == "__shl" and
708 a>>1 == "__shr")
709assert (a==b and a.op == "__eq")
710assert (a>=b and a.op == "__le")
711assert (a>b and a.op == "__lt")
712assert(~a == "__bnot")
713
714do -- testing for-iterator name
715 local function f()
716 assert(debug.getinfo(1).name == "for iterator")
717 end
718
719 for i in f do end
720end
721
722
723do -- testing debug info for finalizers
724 local name = nil
725
726 -- create a piece of garbage with a finalizer
727 setmetatable({}, {__gc = function ()
728 local t = debug.getinfo(2) -- get callee information
729 assert(t.namewhat == "metamethod")
730 name = t.name
731 end})
732
733 -- repeat until previous finalizer runs (setting 'name')
734 repeat local a = {} until name
735 assert(name == "__gc")
736end
737
738
739do
740 print("testing traceback sizes")
741
742 local function countlines (s)
743 return select(2, string.gsub(s, "\n", ""))
744 end
745
746 local function deep (lvl, n)
747 if lvl == 0 then
748 return (debug.traceback("message", n))
749 else
750 return (deep(lvl-1, n))
751 end
752 end
753
754 local function checkdeep (total, start)
755 local s = deep(total, start)
756 local rest = string.match(s, "^message\nstack traceback:\n(.*)$")
757 local cl = countlines(rest)
758 -- at most 10 lines in first part, 11 in second, plus '...'
759 assert(cl <= 10 + 11 + 1)
760 local brk = string.find(rest, "%.%.%.")
761 if brk then -- does message have '...'?
762 local rest1 = string.sub(rest, 1, brk)
763 local rest2 = string.sub(rest, brk, #rest)
764 assert(countlines(rest1) == 10 and countlines(rest2) == 11)
765 else
766 assert(cl == total - start + 2)
767 end
768 end
769
770 for d = 1, 51, 10 do
771 for l = 1, d do
772 -- use coroutines to ensure complete control of the stack
773 coroutine.wrap(checkdeep)(d, l)
774 end
775 end
776
777end
778
779
780print("testing debug functions on chunk without debug info")
781prog = [[-- program to be loaded without debug information
782local debug = require'debug'
783local a = 12 -- a local variable
784
785local n, v = debug.getlocal(1, 1)
786assert(n == "(*temporary)" and v == debug) -- unkown name but known value
787n, v = debug.getlocal(1, 2)
788assert(n == "(*temporary)" and v == 12) -- unkown name but known value
789
790-- a function with an upvalue
791local f = function () local x; return a end
792n, v = debug.getupvalue(f, 1)
793assert(n == "(*no name)" and v == 12)
794assert(debug.setupvalue(f, 1, 13) == "(*no name)")
795assert(a == 13)
796
797local t = debug.getinfo(f)
798assert(t.name == nil and t.linedefined > 0 and
799 t.lastlinedefined == t.linedefined and
800 t.short_src == "?")
801assert(debug.getinfo(1).currentline == -1)
802
803t = debug.getinfo(f, "L").activelines
804assert(next(t) == nil) -- active lines are empty
805
806-- dump/load a function without debug info
807f = load(string.dump(f))
808
809t = debug.getinfo(f)
810assert(t.name == nil and t.linedefined > 0 and
811 t.lastlinedefined == t.linedefined and
812 t.short_src == "?")
813assert(debug.getinfo(1).currentline == -1)
814
815return a
816]]
817
818
819-- load 'prog' without debug info
820local f = assert(load(string.dump(load(prog), true)))
821
822assert(f() == 13)
823
824do -- tests for 'source' in binary dumps
825 local prog = [[
826 return function (x)
827 return function (y)
828 return x + y
829 end
830 end
831 ]]
832 local name = string.rep("x", 1000)
833 local p = assert(load(prog, name))
834 -- load 'p' as a binary chunk with debug information
835 local c = string.dump(p)
836 assert(#c > 1000 and #c < 2000) -- no repetition of 'source' in dump
837 local f = assert(load(c))
838 local g = f()
839 local h = g(3)
840 assert(h(5) == 8)
841 assert(debug.getinfo(f).source == name and -- all functions have 'source'
842 debug.getinfo(g).source == name and
843 debug.getinfo(h).source == name)
844 -- again, without debug info
845 local c = string.dump(p, true)
846 assert(#c < 500) -- no 'source' in dump
847 local f = assert(load(c))
848 local g = f()
849 local h = g(30)
850 assert(h(50) == 80)
851 assert(debug.getinfo(f).source == '=?' and -- no function has 'source'
852 debug.getinfo(g).source == '=?' and
853 debug.getinfo(h).source == '=?')
854end
855
856print"OK"
857