@@ -573,16 +573,16 @@ local undump55; do
573573 local function LoadString()
574574 local size = LoadUnsigned(math.maxinteger)
575575 if size == 0 then
576- return nil
577- end
578- if size == 1 then
579576 local idx = LoadUnsigned(math.maxinteger)
577+ if idx == 0 then
578+ return nil
579+ end
580580 if not cached[idx] then
581581 error("invalid string index")
582582 end
583583 return cached[idx]
584584 end
585- local str = LoadCharN(size - 1 )
585+ local str = LoadCharN(size)
586586 cached[#cached + 1] = str
587587 return str
588588 end
@@ -689,7 +689,7 @@ local undump55; do
689689 f.linedefined = LoadInt()
690690 f.lastlinedefined = LoadInt()
691691 f.numparams = LoadByte()
692- f.is_vararg = LoadByte() & 1
692+ f.is_vararg = LoadByte() & 3
693693 f.maxstacksize = LoadByte()
694694 LoadCode(f)
695695 LoadConstants(f)
@@ -748,11 +748,10 @@ return function(bytes)
748748end
749749]]
750750
751- local coverage_start ; do
752- local debug_getinfo = debug.getinfo
751+ local coverage = {}; do
753752 local include = {}
754- local m = {}
755753 local undump
754+ local enable = false
756755
757756 local function nextline (proto , abs , currentline , pc )
758757 local line = proto .lineinfo [pc ]
@@ -763,6 +762,28 @@ local coverage_start; do
763762 end
764763 end
765764
765+ local function calc_actives_55 (proto , actives )
766+ local currentline = proto .linedefined
767+ local abs = {}
768+ for _ , line in ipairs (proto .abslineinfo ) do
769+ abs [line .pc ] = line .line
770+ end
771+ local start = 1
772+ if proto .is_vararg > 0 then
773+ local OP_VARARGPREP = 83
774+ assert (proto .code [1 ] % 128 == OP_VARARGPREP )
775+ currentline = nextline (proto , abs , currentline , 1 )
776+ start = 2
777+ end
778+ for pc = start , # proto .lineinfo do
779+ currentline = nextline (proto , abs , currentline , pc )
780+ actives [currentline ] = true
781+ end
782+ for i = 1 , proto .sizep do
783+ calc_actives_55 (proto .p [i ], actives )
784+ end
785+ end
786+
766787 local function calc_actives_54 (proto , actives )
767788 local currentline = proto .linedefined
768789 local abs = {}
@@ -771,7 +792,8 @@ local coverage_start; do
771792 end
772793 local start = 1
773794 if proto .is_vararg > 0 then
774- assert (proto .code [1 ] % 128 == 81 ) -- OP_VARARGPREP
795+ local OP_VARARGPREP = 81
796+ assert (proto .code [1 ] % 128 == OP_VARARGPREP )
775797 currentline = nextline (proto , abs , currentline , 1 )
776798 start = 2
777799 end
@@ -805,7 +827,9 @@ local coverage_start; do
805827 end
806828 local cl , version = undump (string.dump (assert (load (source ))))
807829 local actives = {}
808- if version >= 0x54 then
830+ if version >= 0x55 then
831+ calc_actives_55 (cl .f , actives )
832+ elseif version == 0x54 then
809833 calc_actives_54 (cl .f , actives )
810834 else
811835 calc_actives_53 (cl .f , actives )
@@ -831,33 +855,43 @@ local coverage_start; do
831855 end
832856
833857 local function debug_hook (_ , lineno )
834- local file = include [debug_getinfo (2 , " S" ).source ]
858+ local file = include [debug.getinfo (2 , " S" ).source ]
835859 if file then
836860 file [lineno ] = true
837861 end
838862 end
839863
840- function m .include (source , name )
864+ function coverage .start ()
865+ enable = true
866+ undump = assert (load (undump_script ))()
867+ debug.sethook (debug_hook , " l" )
868+ end
869+
870+ function coverage .include (name )
871+ if not enable then
872+ return
873+ end
874+ local path = assert (package.searchpath (name , package.path ))
875+ local f = assert (loadfile (path ))
876+ local source = debug.getinfo (f , " S" ).source
841877 if include [source ] then
842878 include [source ].name = name
843879 else
844880 include [source ] = { name = name }
845881 end
846882 end
847883
848- function m .start (co )
849- if co then
850- debug.sethook (co , debug_hook , " l" )
851- else
852- debug.sethook (debug_hook , " l" )
884+ function coverage .stop ()
885+ if not enable then
886+ return
853887 end
854- end
855-
856- function m .stop ()
857888 debug.sethook ()
858889 end
859890
860- function m .result ()
891+ function coverage .print_result ()
892+ if not enable then
893+ return
894+ end
861895 local str = {}
862896 for source , file in sortpairs (include ) do
863897 local actives = get_actives (source )
@@ -882,23 +916,17 @@ local coverage_start; do
882916 lines [# lines + 1 ] = tostring (i )
883917 end
884918 end
885- str [# str + 1 ] = string.format (" coverage: %02.02f%% (%d/%d) %s " , pass / total * 100 , pass , total , file .name )
919+ str [# str + 1 ] = string.format (" coverage: %02.02f%% (%d/%d) module `%s` " , pass / total * 100 , pass , total , file .name )
886920 if # lines > 0 then
887921 str [# str + 1 ] = table.concat (lines , " " )
888922 str [# str + 1 ] = table.concat (status )
889923 end
890924 end
891- return table.concat (str , " \n " )
892- end
893-
894- function coverage_start ()
895- undump = assert (load (undump_script ))()
896- return m
925+ print (table.concat (str , " \n " ))
897926 end
898927end
899928
900929local m = {}
901- local coverage
902930
903931local function split (str )
904932 local r = {}
@@ -1313,9 +1341,7 @@ function m.run()
13131341 end
13141342 end
13151343 local duration = os.clock () - startTime
1316- if coverage then
1317- coverage .stop ()
1318- end
1344+ coverage .stop ()
13191345 if options .verbosity then
13201346 print (" =========================================================" )
13211347 else
@@ -1331,21 +1357,18 @@ function m.run()
13311357 print ()
13321358 end
13331359 end
1334- if coverage then
1335- print ( coverage . result ())
1336- end
1337- local s = string.format (" Ran %d tests in %0.3f seconds, %d successes, %d failures" , # selected , duration , successes , # failures )
1338- if # selected - successes - # failures > 0 then
1339- s = s .. string.format (" , %d skipped" , ( # selected - successes - # failures ))
1360+ coverage . print_result ()
1361+ local skipped = # selected - successes - # failures
1362+ if skipped <= 0 then
1363+ print ( string.format (" Ran %d tests in %0.3f seconds, %d successes, %d failures" , # selected , duration , successes , # failures ) )
1364+ else
1365+ print ( string.format (" Ran %d tests in %0.3f seconds , %d successes, %d failures, %d skipped" , # selected , duration , successes , # failures , skipped ))
13401366 end
1341- print (s )
13421367 if # failures == 0 then
13431368 print (" OK" )
13441369 if options .touch then
13451370 touch (options .touch )
13461371 end
1347- end
1348- if # failures == 0 then
13491372 return 0
13501373 end
13511374 return 1
@@ -1356,26 +1379,19 @@ function m.skip(name)
13561379end
13571380
13581381function m .moduleCoverage (name )
1359- if not coverage then
1360- return
1361- end
1362- local path = assert (package.searchpath (name , package.path ))
1363- local f = assert (loadfile (path ))
1364- local source = debug.getinfo (f , " S" ).source
1365- coverage .include (source , (" module `%s`" ):format (name ))
1382+ coverage .include (name )
13661383end
13671384
1385+ m .options = options
1386+ m .stringify = stringify
1387+
13681388if options .coverage then
1369- local LuaVersion = (function ()
1370- local major , minor = _VERSION :match " Lua (%d)%.(%d)"
1371- return tonumber (major ) * 10 + tonumber (minor )
1372- end )()
1373- if LuaVersion == 53 or LuaVersion == 54 or LuaVersion == 55 then
1374- coverage = coverage_start ()
1375- coverage .start ()
1389+ local major , minor = _VERSION :match " Lua (%d)%.(%d)"
1390+ if major == " 5" then
1391+ if minor == " 3" or minor == " 4" or minor == " 5" then
1392+ coverage .start ()
1393+ end
13761394 end
13771395end
1378- m .options = options
1379- m .stringify = stringify
13801396
13811397return m
0 commit comments