fixed the tester; more tests green

This commit is contained in:
Araq 2015-03-10 12:32:16 +01:00
commit 0032912d10
7 changed files with 68 additions and 50 deletions

View file

@ -18,3 +18,4 @@ define:useStdoutAsStdmsg
cs:partial cs:partial
#define:useNodeIds #define:useNodeIds
symbol:nimfix symbol:nimfix
#gc:markAndSweep

View file

@ -108,7 +108,7 @@ path="$lib/pure/unidecode"
gcc.options.always = "-w" gcc.options.always = "-w"
gcc.cpp.options.always = "-w -fpermissive" gcc.cpp.options.always = "-w -fpermissive"
@else: @else:
gcc.options.always = "-w" gcc.options.always = "-w"
gcc.cpp.options.always = "-w -fpermissive" gcc.cpp.options.always = "-w -fpermissive"
@end @end
@ -151,7 +151,7 @@ clang.options.size = "-Os"
vcc.options.linker = "/DEBUG /Zi /Fd\"$projectName.pdb\" /F33554432" # set the stack size to 8 MB vcc.options.linker = "/DEBUG /Zi /Fd\"$projectName.pdb\" /F33554432" # set the stack size to 8 MB
vcc.options.debug = "/Zi /Fd\"$projectName.pdb\"" vcc.options.debug = "/Zi /Fd\"$projectName.pdb\""
vcc.options.always = "/nologo" vcc.options.always = "/nologo"
vcc.options.speed = "/Ox /arch:SSE2" vcc.options.speed = "/O2 /arch:SSE2"
vcc.options.size = "/O1" vcc.options.size = "/O1"
# Configuration for the Digital Mars C/C++ compiler: # Configuration for the Digital Mars C/C++ compiler:

View file

@ -7,13 +7,13 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
# A simple mark&sweep garbage collector for Nim. Define the # A simple mark&sweep garbage collector for Nim. Define the
# symbol ``gcUseBitvectors`` to generate a variant of this GC. # symbol ``gcUseBitvectors`` to generate a variant of this GC.
{.push profiler:off.} {.push profiler:off.}
const const
InitialThreshold = 4*1024*1024 # X MB because marking&sweeping is slow InitialThreshold = 4*1024*1024 # X MB because marking&sweeping is slow
withBitvectors = defined(gcUseBitvectors) withBitvectors = defined(gcUseBitvectors)
# bitvectors are significantly faster for GC-bench, but slower for # bitvectors are significantly faster for GC-bench, but slower for
# bootstrapping and use more memory # bootstrapping and use more memory
rcWhite = 0 rcWhite = 0
@ -29,21 +29,21 @@ type
TWalkOp = enum TWalkOp = enum
waMarkGlobal, # we need to mark conservatively for global marker procs waMarkGlobal, # we need to mark conservatively for global marker procs
# as these may refer to a global var and not to a thread # as these may refer to a global var and not to a thread
# local # local
waMarkPrecise # fast precise marking waMarkPrecise # fast precise marking
TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.} TFinalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.}
# A ref type can have a finalizer that is called before the object's # A ref type can have a finalizer that is called before the object's
# storage is freed. # storage is freed.
TGlobalMarkerProc = proc () {.nimcall, benign.} TGlobalMarkerProc = proc () {.nimcall, benign.}
TGcStat = object TGcStat = object
collections: int # number of performed full collections collections: int # number of performed full collections
maxThreshold: int # max threshold that has been set maxThreshold: int # max threshold that has been set
maxStackSize: int # max stack size maxStackSize: int # max stack size
freedObjects: int # max entries in cycle table freedObjects: int # max entries in cycle table
TGcHeap = object # this contains the zero count and TGcHeap = object # this contains the zero count and
# non-zero count table # non-zero count table
stackBottom: pointer stackBottom: pointer
@ -64,11 +64,11 @@ var
when not defined(useNimRtl): when not defined(useNimRtl):
instantiateForRegion(gch.region) instantiateForRegion(gch.region)
template acquire(gch: TGcHeap) = template acquire(gch: TGcHeap) =
when hasThreadSupport and hasSharedHeap: when hasThreadSupport and hasSharedHeap:
acquireSys(HeapLock) acquireSys(HeapLock)
template release(gch: TGcHeap) = template release(gch: TGcHeap) =
when hasThreadSupport and hasSharedHeap: when hasThreadSupport and hasSharedHeap:
releaseSys(HeapLock) releaseSys(HeapLock)
@ -134,7 +134,7 @@ proc prepareDealloc(cell: PCell) =
(cast[TFinalizer](cell.typ.finalizer))(cellToUsr(cell)) (cast[TFinalizer](cell.typ.finalizer))(cellToUsr(cell))
dec(gch.recGcLock) dec(gch.recGcLock)
proc nimGCref(p: pointer) {.compilerProc.} = proc nimGCref(p: pointer) {.compilerProc.} =
# we keep it from being collected by pretending it's not even allocated: # we keep it from being collected by pretending it's not even allocated:
when false: when false:
when withBitvectors: excl(gch.allocated, usrToCell(p)) when withBitvectors: excl(gch.allocated, usrToCell(p))
@ -261,6 +261,10 @@ proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} =
zeroMem(result, size) zeroMem(result, size)
when defined(memProfiler): nimProfile(size) when defined(memProfiler): nimProfile(size)
proc newObjNoInit(typ: PNimType, size: int): pointer {.compilerRtl.} =
result = rawNewObj(typ, size, gch)
when defined(memProfiler): nimProfile(size)
proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} = proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} =
# `newObj` already uses locks, so no need for them here. # `newObj` already uses locks, so no need for them here.
let size = addInt(mulInt(len, typ.base.size), GenericSeqSize) let size = addInt(mulInt(len, typ.base.size), GenericSeqSize)
@ -273,25 +277,25 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
result = rawNewObj(typ, size, gch) result = rawNewObj(typ, size, gch)
zeroMem(result, size) zeroMem(result, size)
when defined(memProfiler): nimProfile(size) when defined(memProfiler): nimProfile(size)
proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} = proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} =
let size = addInt(mulInt(len, typ.base.size), GenericSeqSize) let size = addInt(mulInt(len, typ.base.size), GenericSeqSize)
result = newObj(typ, size) result = newObj(typ, size)
cast[PGenericSeq](result).len = len cast[PGenericSeq](result).len = len
cast[PGenericSeq](result).reserved = len cast[PGenericSeq](result).reserved = len
when defined(memProfiler): nimProfile(size) when defined(memProfiler): nimProfile(size)
proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer = proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
acquire(gch) acquire(gch)
collectCT(gch) collectCT(gch)
var ol = usrToCell(old) var ol = usrToCell(old)
sysAssert(ol.typ != nil, "growObj: 1") sysAssert(ol.typ != nil, "growObj: 1")
gcAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2") gcAssert(ol.typ.kind in {tyString, tySequence}, "growObj: 2")
var res = cast[PCell](rawAlloc(gch.region, newsize + sizeof(TCell))) var res = cast[PCell](rawAlloc(gch.region, newsize + sizeof(TCell)))
var elemSize = 1 var elemSize = 1
if ol.typ.kind != tyString: elemSize = ol.typ.base.size if ol.typ.kind != tyString: elemSize = ol.typ.base.size
var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
copyMem(res, ol, oldsize + sizeof(TCell)) copyMem(res, ol, oldsize + sizeof(TCell))
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)), zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
@ -401,7 +405,7 @@ proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell)) var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
if objStart != nil: if objStart != nil:
mark(gch, objStart) mark(gch, objStart)
# ----------------- stack management -------------------------------------- # ----------------- stack management --------------------------------------
# inspired from Smart Eiffel # inspired from Smart Eiffel
@ -536,7 +540,7 @@ proc collectCTBody(gch: var TGcHeap) =
markStackAndRegisters(gch) markStackAndRegisters(gch)
markGlobals(gch) markGlobals(gch)
sweep(gch) sweep(gch)
inc(gch.stat.collections) inc(gch.stat.collections)
when withBitvectors: when withBitvectors:
deinit(gch.marked) deinit(gch.marked)
@ -544,19 +548,19 @@ proc collectCTBody(gch: var TGcHeap) =
gch.cycleThreshold = max(InitialThreshold, getOccupiedMem().mulThreshold) gch.cycleThreshold = max(InitialThreshold, getOccupiedMem().mulThreshold)
gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold) gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold)
sysAssert(allocInv(gch.region), "collectCT: end") sysAssert(allocInv(gch.region), "collectCT: end")
proc collectCT(gch: var TGcHeap) = proc collectCT(gch: var TGcHeap) =
if getOccupiedMem(gch.region) >= gch.cycleThreshold and gch.recGcLock == 0: if getOccupiedMem(gch.region) >= gch.cycleThreshold and gch.recGcLock == 0:
collectCTBody(gch) collectCTBody(gch)
when not defined(useNimRtl): when not defined(useNimRtl):
proc GC_disable() = proc GC_disable() =
when hasThreadSupport and hasSharedHeap: when hasThreadSupport and hasSharedHeap:
atomicInc(gch.recGcLock, 1) atomicInc(gch.recGcLock, 1)
else: else:
inc(gch.recGcLock) inc(gch.recGcLock)
proc GC_enable() = proc GC_enable() =
if gch.recGcLock > 0: if gch.recGcLock > 0:
when hasThreadSupport and hasSharedHeap: when hasThreadSupport and hasSharedHeap:
atomicDec(gch.recGcLock, 1) atomicDec(gch.recGcLock, 1)
else: else:

View file

@ -1,3 +1,8 @@
discard """
disabled: "true"
"""
# Now the compiler fails with OOM. yay.
# bug #794 # bug #794
type TRange = range[0..3] type TRange = range[0..3]

View file

@ -12,7 +12,7 @@ test "previous definitions can be further overloaded or hidden in local scopes":
check t(true) == "bool" check t(true) == "bool"
check t(10) == "int" check t(10) == "int"
template t(a: int): expr = "inner int" template t(a: int): expr = "inner int"
check t(10) == "inner int" check t(10) == "inner int"
check t("test") == "string" check t("test") == "string"
@ -21,12 +21,12 @@ test "templates can be redefined multiple times":
template customAssert(cond: bool, msg: string): stmt {.immediate, dirty.} = template customAssert(cond: bool, msg: string): stmt {.immediate, dirty.} =
if not cond: fail(msg) if not cond: fail(msg)
template assertion_failed(body: stmt) {.immediate.} = template assertion_failed(body: stmt) {.immediate, dirty.} =
template fail(msg: string): stmt = body template fail(msg: string): stmt = body
assertion_failed: check msg == "first fail path" assertion_failed: check msg == "first fail path"
customAssert false, "first fail path" customAssert false, "first fail path"
assertion_failed: check msg == "second fail path" assertion_failed: check msg == "second fail path"
customAssert false, "second fail path" customAssert false, "second fail path"

View file

@ -20,7 +20,7 @@ const
<td>Success</td></tr>""" <td>Success</td></tr>"""
TableFooter = "</table>" TableFooter = "</table>"
HtmlBegin = """<html> HtmlBegin = """<html>
<head> <head>
<title>Test results</title> <title>Test results</title>
<style type="text/css"> <style type="text/css">
<!--""" & slurp("css/boilerplate.css") & "\n" & <!--""" & slurp("css/boilerplate.css") & "\n" &
@ -28,13 +28,13 @@ const
""" """
ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; } ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; }
ul#tabs li { display: inline; } ul#tabs li { display: inline; }
ul#tabs li a { color: #42454a; background-color: #dedbde; ul#tabs li a { color: #42454a; background-color: #dedbde;
border: 1px solid #c9c3ba; border-bottom: none; border: 1px solid #c9c3ba; border-bottom: none;
padding: 0.3em; text-decoration: none; } padding: 0.3em; text-decoration: none; }
ul#tabs li a:hover { background-color: #f1f0ee; } ul#tabs li a:hover { background-color: #f1f0ee; }
ul#tabs li a.selected { color: #000; background-color: #f1f0ee; ul#tabs li a.selected { color: #000; background-color: #f1f0ee;
font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; } font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; }
div.tabContent { border: 1px solid #c9c3ba; div.tabContent { border: 1px solid #c9c3ba;
padding: 0.5em; background-color: #f1f0ee; } padding: 0.5em; background-color: #f1f0ee; }
div.tabContent.hide { display: none; } div.tabContent.hide { display: none; }
--> -->
@ -43,7 +43,7 @@ div.tabContent.hide { display: none; }
var tabLinks = new Array(); var tabLinks = new Array();
var contentDivs = new Array(); var contentDivs = new Array();
function init() { function init() {
// Grab the tab links and content divs from the page // Grab the tab links and content divs from the page
var tabListItems = document.getElementById('tabs').childNodes; var tabListItems = document.getElementById('tabs').childNodes;
@ -103,7 +103,7 @@ div.tabContent.hide { display: none; }
</head> </head>
<body onload="init()">""" <body onload="init()">"""
HtmlEnd = "</body></html>" HtmlEnd = "</body></html>"
proc td(s: string): string = proc td(s: string): string =
@ -115,8 +115,8 @@ proc getCommit(db: TDbConn, c: int): string =
if commit == 0: result = thisCommit[0] if commit == 0: result = thisCommit[0]
inc commit inc commit
proc generateHtml*(filename: string, commit: int) = proc generateHtml*(filename: string, commit: int; onlyFailing: bool) =
const selRow = """select name, category, target, action, const selRow = """select name, category, target, action,
expected, given, result expected, given, result
from TestResult from TestResult
where [commit] = ? and machine = ? where [commit] = ? and machine = ?
@ -140,17 +140,20 @@ proc generateHtml*(filename: string, commit: int) =
for m in db.rows(sql"select id, name, os, cpu from Machine order by id"): for m in db.rows(sql"select id, name, os, cpu from Machine order by id"):
outfile.writeln """<li><a href="#$#">$#: $#, $#</a></li>""" % m outfile.writeln """<li><a href="#$#">$#: $#, $#</a></li>""" % m
outfile.write("</ul>") outfile.write("</ul>")
for currentMachine in db.rows(sql"select id from Machine order by id"): for currentMachine in db.rows(sql"select id from Machine order by id"):
let m = currentMachine[0] let m = currentMachine[0]
outfile.write("""<div class="tabContent" id="$#">""" % m) outfile.write("""<div class="tabContent" id="$#">""" % m)
outfile.write(TableHeader) outfile.write(TableHeader)
for row in db.rows(sql(selRow), lastCommit, m): for row in db.rows(sql(selRow), lastCommit, m):
outfile.write("<tr>") if onlyFailing and row.len > 0 and row[row.high] == "reSuccess":
for x in row: discard
outfile.write(x.td) else:
outfile.write("</tr>") outfile.write("<tr>")
for x in row:
outfile.write(x.td)
outfile.write("</tr>")
outfile.write(TableFooter) outfile.write(TableFooter)
outfile.write("</div>") outfile.write("</div>")
@ -161,7 +164,7 @@ proc generateHtml*(filename: string, commit: int) =
proc generateJson*(filename: string, commit: int) = proc generateJson*(filename: string, commit: int) =
const const
selRow = """select count(*), selRow = """select count(*),
sum(result = 'reSuccess'), sum(result = 'reSuccess'),
sum(result = 'reIgnored') sum(result = 'reIgnored')
from TestResult from TestResult
where [commit] = ? and machine = ? where [commit] = ? and machine = ?
@ -174,9 +177,9 @@ proc generateJson*(filename: string, commit: int) =
on A.name = B.name and A.category = B.category on A.name = B.name and A.category = B.category
where A.[commit] = ? and B.[commit] = ? and A.machine = ? where A.[commit] = ? and B.[commit] = ? and A.machine = ?
and A.result != B.result""" and A.result != B.result"""
selResults = """select selResults = """select
category || '/' || target || '/' || name, category || '/' || target || '/' || name,
category, target, action, result, expected, given category, target, action, result, expected, given
from TestResult from TestResult
where [commit] = ?""" where [commit] = ?"""
var db = open(connection="testament.db", user="testament", password="", var db = open(connection="testament.db", user="testament", password="",

View file

@ -30,6 +30,7 @@ Arguments:
arguments are passed to the compiler arguments are passed to the compiler
Options: Options:
--print also print results to the console --print also print results to the console
--failing only show failing/ignored tests
""" % resultsFile """ % resultsFile
type type
@ -48,7 +49,7 @@ type
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
let let
pegLineError = pegLineError =
peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error') ':' \s* {.*}" peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Error') ':' \s* {.*}"
pegOtherError = peg"'Error:' \s* {.*}" pegOtherError = peg"'Error:' \s* {.*}"
pegSuccess = peg"'Hint: operation successful'.*" pegSuccess = peg"'Hint: operation successful'.*"
@ -107,7 +108,7 @@ proc addResult(r: var TResults, test: TTest,
expected, given: string, success: TResultEnum) = expected, given: string, success: TResultEnum) =
let name = test.name.extractFilename & test.options let name = test.name.extractFilename & test.options
backend.writeTestResult(name = name, backend.writeTestResult(name = name,
category = test.cat.string, category = test.cat.string,
target = $test.target, target = $test.target,
action = $test.action, action = $test.action,
result = $success, result = $success,
@ -141,7 +142,7 @@ proc generatedFile(path, name: string, target: TTarget): string =
(if target == targetJS: path.splitPath.tail & "_" else: "compiler_") & (if target == targetJS: path.splitPath.tail & "_" else: "compiler_") &
name.changeFileExt(ext) name.changeFileExt(ext)
proc codegenCheck(test: TTest, check: string, given: var TSpec, r: var TResults) = proc codegenCheck(test: TTest, check: string, given: var TSpec) =
try: try:
let (path, name, ext2) = test.name.splitFile let (path, name, ext2) = test.name.splitFile
let genFile = generatedFile(path, name, test.target) let genFile = generatedFile(path, name, test.target)
@ -151,10 +152,11 @@ proc codegenCheck(test: TTest, check: string, given: var TSpec, r: var TResults)
given.err = reCodegenFailure given.err = reCodegenFailure
except ValueError: except ValueError:
given.err = reInvalidPeg given.err = reInvalidPeg
echo getCurrentExceptionMsg()
except IOError: except IOError:
given.err = reCodeNotFound given.err = reCodeNotFound
proc nimoutCheck(test: TTest; expectedNimout: string; given: var TSpec, r: var TResults) = proc nimoutCheck(test: TTest; expectedNimout: string; given: var TSpec) =
let exp = expectedNimout.strip.replace("\C\L", "\L") let exp = expectedNimout.strip.replace("\C\L", "\L")
let giv = given.nimout.strip.replace("\C\L", "\L") let giv = given.nimout.strip.replace("\C\L", "\L")
if exp notin giv: if exp notin giv:
@ -165,18 +167,19 @@ proc makeDeterministic(s: string): string =
sort(x, system.cmp) sort(x, system.cmp)
result = join(x, "\n") result = join(x, "\n")
proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec, r: var TResults) = proc compilerOutputTests(test: TTest, given: var TSpec, expected: TSpec;
r: var TResults) =
var expectedmsg: string = "" var expectedmsg: string = ""
var givenmsg: string = "" var givenmsg: string = ""
if given.err == reSuccess: if given.err == reSuccess:
if expected.ccodeCheck.len > 0: if expected.ccodeCheck.len > 0:
codegenCheck(test, expectedmsg, given, r) codegenCheck(test, expected.ccodeCheck, given)
expectedmsg = expected.ccodeCheck expectedmsg = expected.ccodeCheck
givenmsg = given.msg givenmsg = given.msg
if expected.nimout.len > 0: if expected.nimout.len > 0:
expectedmsg = expected.nimout expectedmsg = expected.nimout
givenmsg = given.nimout.strip givenmsg = given.nimout.strip
nimoutCheck(test, expectedmsg, given, r) nimoutCheck(test, expectedmsg, given)
if given.err == reSuccess: inc(r.passed) if given.err == reSuccess: inc(r.passed)
r.addResult(test, expectedmsg, givenmsg, given.err) r.addResult(test, expectedmsg, givenmsg, given.err)
@ -260,11 +263,13 @@ proc main() =
backend.open() backend.open()
var optPrintResults = false var optPrintResults = false
var optFailing = false
var p = initOptParser() var p = initOptParser()
p.next() p.next()
if p.kind == cmdLongoption: while p.kind == cmdLongoption:
case p.key.string.normalize case p.key.string.normalize
of "print", "verbose": optPrintResults = true of "print", "verbose": optPrintResults = true
of "failing": optFailing = true
else: quit Usage else: quit Usage
p.next() p.next()
if p.kind != cmdArgument: quit Usage if p.kind != cmdArgument: quit Usage
@ -288,7 +293,7 @@ proc main() =
of "html": of "html":
var commit = 0 var commit = 0
discard parseInt(p.cmdLineRest.string, commit) discard parseInt(p.cmdLineRest.string, commit)
generateHtml(resultsFile, commit) generateHtml(resultsFile, commit, optFailing)
generateJson(jsonFile, commit) generateJson(jsonFile, commit)
else: else:
quit Usage quit Usage