Compare commits
10 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c504653a42 | ||
|
|
373a79b28a | ||
|
|
4bb0e58992 | ||
|
|
db4710a1c6 | ||
|
|
965e1e1803 | ||
|
|
50e43ea60d | ||
|
|
1fdc9206b3 | ||
|
|
02c6eb10b5 | ||
|
|
aa7cfd3355 | ||
|
|
3a2864c3f5 |
46 changed files with 223 additions and 96 deletions
|
|
@ -130,8 +130,8 @@ proc skipConvAndClosure*(n: PNode): PNode =
|
||||||
proc sameValue*(a, b: PNode): bool =
|
proc sameValue*(a, b: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal == b.intVal
|
if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
|
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
|
|
@ -145,8 +145,8 @@ proc leValue*(a, b: PNode): bool =
|
||||||
# a <= b?
|
# a <= b?
|
||||||
result = false
|
result = false
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkCharLit..nkUInt32Lit:
|
||||||
if b.kind in {nkCharLit..nkInt64Lit}: result = a.intVal <= b.intVal
|
if b.kind in {nkCharLit..nkUInt32Lit}: result = a.intVal <= b.intVal
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal
|
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
|
|
|
||||||
|
|
@ -130,9 +130,11 @@ proc commonType*(x, y: PType): PType =
|
||||||
elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
|
elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
|
||||||
var nt: PType
|
var nt: PType
|
||||||
for i in 0.. <a.len:
|
for i in 0.. <a.len:
|
||||||
if isEmptyContainer(a.sons[i]) and not isEmptyContainer(b.sons[i]):
|
let aEmpty = isEmptyContainer(a.sons[i])
|
||||||
|
let bEmpty = isEmptyContainer(b.sons[i])
|
||||||
|
if aEmpty != bEmpty:
|
||||||
if nt.isNil: nt = copyType(a, a.owner, false)
|
if nt.isNil: nt = copyType(a, a.owner, false)
|
||||||
nt.sons[i] = b.sons[i]
|
nt.sons[i] = if aEmpty: b.sons[i] else: a.sons[i]
|
||||||
if not nt.isNil: result = nt
|
if not nt.isNil: result = nt
|
||||||
#elif b.sons[idx].kind == tyEmpty: return x
|
#elif b.sons[idx].kind == tyEmpty: return x
|
||||||
elif a.kind == tyRange and b.kind == tyRange:
|
elif a.kind == tyRange and b.kind == tyRange:
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,7 @@ proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
|
||||||
|
|
||||||
proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
||||||
result = newTypeS(tyFromExpr, c)
|
result = newTypeS(tyFromExpr, c)
|
||||||
|
assert n != nil
|
||||||
result.n = n
|
result.n = n
|
||||||
|
|
||||||
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
||||||
|
|
|
||||||
|
|
@ -448,20 +448,25 @@ proc changeType(n: PNode, newType: PType, check: bool) =
|
||||||
let tup = newType.skipTypes({tyGenericInst})
|
let tup = newType.skipTypes({tyGenericInst})
|
||||||
if tup.kind != tyTuple:
|
if tup.kind != tyTuple:
|
||||||
internalError(n.info, "changeType: no tuple type for constructor")
|
internalError(n.info, "changeType: no tuple type for constructor")
|
||||||
elif newType.n == nil: discard
|
|
||||||
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
|
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
|
||||||
|
# named tuple?
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var m = n.sons[i].sons[0]
|
var m = n.sons[i].sons[0]
|
||||||
if m.kind != nkSym:
|
if m.kind != nkSym:
|
||||||
internalError(m.info, "changeType(): invalid tuple constr")
|
internalError(m.info, "changeType(): invalid tuple constr")
|
||||||
return
|
return
|
||||||
|
if tup.n != nil:
|
||||||
var f = getSymFromList(newType.n, m.sym.name)
|
var f = getSymFromList(newType.n, m.sym.name)
|
||||||
if f == nil:
|
if f == nil:
|
||||||
internalError(m.info, "changeType(): invalid identifier")
|
internalError(m.info, "changeType(): invalid identifier")
|
||||||
return
|
return
|
||||||
changeType(n.sons[i].sons[1], f.typ, check)
|
changeType(n.sons[i].sons[1], f.typ, check)
|
||||||
|
else:
|
||||||
|
changeType(n.sons[i].sons[1], tup.sons[i], check)
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
|
changeType(n.sons[i], tup.sons[i], check)
|
||||||
|
when false:
|
||||||
var m = n.sons[i]
|
var m = n.sons[i]
|
||||||
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
|
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
|
||||||
addSon(a, newSymNode(newType.n.sons[i].sym))
|
addSon(a, newSymNode(newType.n.sons[i].sym))
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
var def: PNode
|
var def: PNode
|
||||||
if a.sons[length-1].kind != nkEmpty:
|
if a.sons[length-1].kind != nkEmpty:
|
||||||
def = semExprWithType(c, a.sons[length-1], {efAllowDestructor})
|
def = semExprWithType(c, a.sons[length-1], {efAllowDestructor})
|
||||||
|
if def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro:
|
||||||
|
# prevent the all too common 'var x = int' bug:
|
||||||
|
localError(def.info, "'typedesc' metatype is not valid here; typed '=' instead of ':'?")
|
||||||
|
def.typ = errorType(c)
|
||||||
if typ != nil:
|
if typ != nil:
|
||||||
if typ.isMetaType:
|
if typ.isMetaType:
|
||||||
def = inferWithMetatype(c, typ, def)
|
def = inferWithMetatype(c, typ, def)
|
||||||
|
|
|
||||||
|
|
@ -781,9 +781,10 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
||||||
result.rawAddSon(paramType)
|
result.rawAddSon(paramType)
|
||||||
|
|
||||||
for i in 0 .. paramType.sonsLen - 2:
|
for i in 0 .. paramType.sonsLen - 2:
|
||||||
let dummyType = if paramType.sons[i].kind == tyStatic: tyUnknown
|
if paramType.sons[i].kind == tyStatic:
|
||||||
else: tyAnything
|
result.rawAddSon makeTypeFromExpr(c, ast.emptyNode) # aka 'tyUnkown'
|
||||||
result.rawAddSon newTypeS(dummyType, c)
|
else:
|
||||||
|
result.rawAddSon newTypeS(tyAnything, c)
|
||||||
|
|
||||||
if paramType.lastSon.kind == tyUserTypeClass:
|
if paramType.lastSon.kind == tyUserTypeClass:
|
||||||
result.kind = tyUserTypeClassInst
|
result.kind = tyUserTypeClassInst
|
||||||
|
|
|
||||||
|
|
@ -1056,7 +1056,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||||
|
|
||||||
of tyFromExpr:
|
of tyFromExpr:
|
||||||
# fix the expression, so it contains the already instantiated types
|
# fix the expression, so it contains the already instantiated types
|
||||||
if f.n == nil: return isGeneric
|
if f.n == nil or f.n.kind == nkEmpty: return isGeneric
|
||||||
let reevaluated = tryResolvingStaticExpr(c, f.n)
|
let reevaluated = tryResolvingStaticExpr(c, f.n)
|
||||||
case reevaluated.typ.kind
|
case reevaluated.typ.kind
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
=====================================================
|
=====================================================
|
||||||
Nim -- a Compiler for Nim. http://nim-lang.org/
|
Nim -- a Compiler for Nim. http://nim-lang.org/
|
||||||
|
|
||||||
Copyright (C) 2006-2014 Andreas Rumpf. All rights reserved.
|
Copyright (C) 2006-2015 Andreas Rumpf. All rights reserved.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,6 @@ Real world example
|
||||||
The installers for the Nim compiler itself are generated by niminst. Have a
|
The installers for the Nim compiler itself are generated by niminst. Have a
|
||||||
look at its configuration file:
|
look at its configuration file:
|
||||||
|
|
||||||
.. include:: compiler/nim.ini
|
.. include:: compiler/installer.ini
|
||||||
:literal:
|
:literal:
|
||||||
|
|
||||||
|
|
|
||||||
14
koch.nim
14
koch.nim
|
|
@ -97,13 +97,13 @@ const
|
||||||
compileNimInst = "-d:useLibzipSrc tools/niminst/niminst"
|
compileNimInst = "-d:useLibzipSrc tools/niminst/niminst"
|
||||||
|
|
||||||
proc csource(args: string) =
|
proc csource(args: string) =
|
||||||
exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/nim.ini $1" %
|
exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/installer.ini $1" %
|
||||||
[args, VersionAsString, compileNimInst, findNim()])
|
[args, VersionAsString, compileNimInst, findNim()])
|
||||||
|
|
||||||
proc zip(args: string) =
|
proc zip(args: string) =
|
||||||
exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/nim.ini" %
|
exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/installer.ini" %
|
||||||
[VersionAsString, compileNimInst, findNim()])
|
[VersionAsString, compileNimInst, findNim()])
|
||||||
exec("$# --var:version=$# --var:mingw=none zip compiler/nim.ini" %
|
exec("$# --var:version=$# --var:mingw=none zip compiler/installer.ini" %
|
||||||
["tools/niminst/niminst".exe, VersionAsString])
|
["tools/niminst/niminst".exe, VersionAsString])
|
||||||
|
|
||||||
proc buildTool(toolname, args: string) =
|
proc buildTool(toolname, args: string) =
|
||||||
|
|
@ -121,20 +121,20 @@ proc nsis(args: string) =
|
||||||
" nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)])
|
" nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)])
|
||||||
|
|
||||||
proc install(args: string) =
|
proc install(args: string) =
|
||||||
exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/nim.ini" %
|
exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/installer.ini" %
|
||||||
[findNim(), compileNimInst, VersionAsString])
|
[findNim(), compileNimInst, VersionAsString])
|
||||||
exec("sh ./install.sh $#" % args)
|
exec("sh ./install.sh $#" % args)
|
||||||
|
|
||||||
proc web(args: string) =
|
proc web(args: string) =
|
||||||
exec("$# cc -r tools/nimweb.nim $# web/nim --putenv:nimversion=$#" %
|
exec("$# cc -r tools/nimweb.nim $# web/website.ini --putenv:nimversion=$#" %
|
||||||
[findNim(), args, VersionAsString])
|
[findNim(), args, VersionAsString])
|
||||||
|
|
||||||
proc website(args: string) =
|
proc website(args: string) =
|
||||||
exec("$# cc -r tools/nimweb.nim $# --website web/nim --putenv:nimversion=$#" %
|
exec("$# cc -r tools/nimweb.nim $# --website web/website.ini --putenv:nimversion=$#" %
|
||||||
[findNim(), args, VersionAsString])
|
[findNim(), args, VersionAsString])
|
||||||
|
|
||||||
proc pdf(args="") =
|
proc pdf(args="") =
|
||||||
exec("$# cc -r tools/nimweb.nim $# --pdf web/nim --putenv:nimversion=$#" %
|
exec("$# cc -r tools/nimweb.nim $# --pdf web/website.ini --putenv:nimversion=$#" %
|
||||||
[findNim(), args, VersionAsString])
|
[findNim(), args, VersionAsString])
|
||||||
|
|
||||||
# -------------- boot ---------------------------------------------------------
|
# -------------- boot ---------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -205,9 +205,13 @@ proc genericReset(dest: pointer, mt: PNimType) =
|
||||||
case mt.kind
|
case mt.kind
|
||||||
of tyString, tyRef, tySequence:
|
of tyString, tyRef, tySequence:
|
||||||
unsureAsgnRef(cast[PPointer](dest), nil)
|
unsureAsgnRef(cast[PPointer](dest), nil)
|
||||||
of tyObject, tyTuple:
|
of tyTuple:
|
||||||
# we don't need to reset m_type field for tyObject
|
|
||||||
genericResetAux(dest, mt.node)
|
genericResetAux(dest, mt.node)
|
||||||
|
of tyObject:
|
||||||
|
genericResetAux(dest, mt.node)
|
||||||
|
# also reset the type field for tyObject, for correct branch switching!
|
||||||
|
var pint = cast[ptr PNimType](dest)
|
||||||
|
pint[] = nil
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
for i in 0..(mt.size div mt.base.size)-1:
|
for i in 0..(mt.size div mt.base.size)-1:
|
||||||
genericReset(cast[pointer](d +% i*% mt.base.size), mt.base)
|
genericReset(cast[pointer](d +% i*% mt.base.size), mt.base)
|
||||||
|
|
|
||||||
|
|
@ -528,11 +528,18 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
||||||
newsize-oldsize)
|
newsize-oldsize)
|
||||||
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
||||||
sysAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
|
# This can be wrong for intermediate temps that are nevertheless on the
|
||||||
#if res.refcount <% rcIncrement:
|
# heap because of lambda lifting:
|
||||||
# add(gch.zct, res)
|
#gcAssert(res.refcount shr rcShift <=% 1, "growObj: 4")
|
||||||
#else: # XXX: what to do here?
|
when logGC:
|
||||||
# decRef(ol)
|
writeCell("growObj old cell", ol)
|
||||||
|
writeCell("growObj new cell", res)
|
||||||
|
gcTrace(ol, csZctFreed)
|
||||||
|
gcTrace(res, csAllocated)
|
||||||
|
when reallyDealloc:
|
||||||
|
sysAssert(allocInv(gch.region), "growObj before dealloc")
|
||||||
|
if ol.refcount shr rcShift <=% 1:
|
||||||
|
# free immediately to save space:
|
||||||
if (ol.refcount and ZctFlag) != 0:
|
if (ol.refcount and ZctFlag) != 0:
|
||||||
var j = gch.zct.len-1
|
var j = gch.zct.len-1
|
||||||
var d = gch.zct.d
|
var d = gch.zct.d
|
||||||
|
|
@ -542,14 +549,15 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
break
|
break
|
||||||
dec(j)
|
dec(j)
|
||||||
if canbeCycleRoot(ol): excl(gch.cycleRoots, ol)
|
if canbeCycleRoot(ol): excl(gch.cycleRoots, ol)
|
||||||
when logGC:
|
|
||||||
writeCell("growObj old cell", ol)
|
|
||||||
writeCell("growObj new cell", res)
|
|
||||||
gcTrace(ol, csZctFreed)
|
|
||||||
gcTrace(res, csAllocated)
|
|
||||||
when reallyDealloc:
|
|
||||||
sysAssert(allocInv(gch.region), "growObj before dealloc")
|
|
||||||
rawDealloc(gch.region, ol)
|
rawDealloc(gch.region, ol)
|
||||||
|
else:
|
||||||
|
# we split the old refcount in 2 parts. XXX This is still not entirely
|
||||||
|
# correct if the pointer that receives growObj's result is on the stack.
|
||||||
|
# A better fix would be to emit the location specific write barrier for
|
||||||
|
# 'growObj', but this is lost of more work and who knows what new problems
|
||||||
|
# this would create.
|
||||||
|
res.refcount = rcIncrement
|
||||||
|
decRef(ol)
|
||||||
else:
|
else:
|
||||||
sysAssert(ol.typ != nil, "growObj: 5")
|
sysAssert(ol.typ != nil, "growObj: 5")
|
||||||
zeroMem(ol, sizeof(TCell))
|
zeroMem(ol, sizeof(TCell))
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,8 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
||||||
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
||||||
newsize-oldsize)
|
newsize-oldsize)
|
||||||
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
||||||
|
when false:
|
||||||
|
# this is wrong since seqs can be shared via 'shallow':
|
||||||
when withBitvectors: excl(gch.allocated, ol)
|
when withBitvectors: excl(gch.allocated, ol)
|
||||||
when reallyDealloc: rawDealloc(gch.region, ol)
|
when reallyDealloc: rawDealloc(gch.region, ol)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,14 @@ proc newPlus(a, b: ref TExpr): ref TPlusExpr =
|
||||||
result.b = b
|
result.b = b
|
||||||
result.op2 = $getOccupiedMem()
|
result.op2 = $getOccupiedMem()
|
||||||
|
|
||||||
|
const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000
|
||||||
|
|
||||||
for i in 0..100_000:
|
for i in 0..100_000:
|
||||||
var s: array[0..11, ref TExpr]
|
var s: array[0..11, ref TExpr]
|
||||||
for j in 0..high(s):
|
for j in 0..high(s):
|
||||||
s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
|
s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
|
||||||
if eval(s[j]) != j+6:
|
if eval(s[j]) != j+6:
|
||||||
quit "error: wrong result"
|
quit "error: wrong result"
|
||||||
if getOccupiedMem() > 500_000: quit("still a leak!")
|
if getOccupiedMem() > Limit: quit("still a leak!")
|
||||||
|
|
||||||
echo "no leak: ", getOccupiedMem()
|
echo "no leak: ", getOccupiedMem()
|
||||||
|
|
|
||||||
29
tests/gc/growobjcrash.nim
Normal file
29
tests/gc/growobjcrash.nim
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
discard """
|
||||||
|
output: "works"
|
||||||
|
"""
|
||||||
|
|
||||||
|
import cgi, strtabs
|
||||||
|
|
||||||
|
proc handleRequest(query: string): StringTableRef =
|
||||||
|
iterator foo(): StringTableRef {.closure.} =
|
||||||
|
var params = {:}.newStringTable()
|
||||||
|
for key, val in cgi.decodeData(query):
|
||||||
|
params[key] = val
|
||||||
|
yield params
|
||||||
|
|
||||||
|
let x = foo
|
||||||
|
result = x()
|
||||||
|
|
||||||
|
const Limit = when compileOption("gc", "markAndSweep"): 5*1024*1024 else: 500_000
|
||||||
|
|
||||||
|
proc main =
|
||||||
|
var counter = 0
|
||||||
|
for i in 0 .. 100_000:
|
||||||
|
for k, v in handleRequest("nick=Elina2&type=activate"):
|
||||||
|
inc counter
|
||||||
|
if counter mod 100 == 0:
|
||||||
|
if getOccupiedMem() > Limit:
|
||||||
|
quit "but now a leak"
|
||||||
|
|
||||||
|
main()
|
||||||
|
echo "works"
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
discard """
|
discard """
|
||||||
output: "2"
|
output: '''2
|
||||||
|
88'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type
|
type
|
||||||
TValue* {.pure, final.} = object of TObject
|
TValue* {.pure, final.} = object of RootObj
|
||||||
a: int
|
a: int
|
||||||
PValue = ref TValue
|
PValue = ref TValue
|
||||||
PPValue = ptr PValue
|
PPValue = ptr PValue
|
||||||
|
|
@ -16,3 +17,19 @@ var sp: PPValue = addr x
|
||||||
sp.a = 2
|
sp.a = 2
|
||||||
if sp.a == 2: echo 2 # with sp[].a the error is gone
|
if sp.a == 2: echo 2 # with sp[].a the error is gone
|
||||||
|
|
||||||
|
# Test the new auto-deref a little
|
||||||
|
|
||||||
|
{.experimental.}
|
||||||
|
|
||||||
|
proc p(x: var int; y: int) = x += y
|
||||||
|
|
||||||
|
block:
|
||||||
|
var x: ref int
|
||||||
|
new(x)
|
||||||
|
|
||||||
|
x.p(44)
|
||||||
|
|
||||||
|
var indirect = p
|
||||||
|
x.indirect(44)
|
||||||
|
|
||||||
|
echo x[]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "expression 'generate(builder)' has no type (or is ambiguous)"
|
||||||
|
"""
|
||||||
|
|
||||||
# bug #898
|
# bug #898
|
||||||
|
|
||||||
proc measureTime(e: auto) =
|
proc measureTime(e: auto) =
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ accept bar(vbar)
|
||||||
accept baz(vbar)
|
accept baz(vbar)
|
||||||
accept baz(vbaz)
|
accept baz(vbaz)
|
||||||
|
|
||||||
reject baz(vnotbaz)
|
#reject baz(vnotbaz) # XXX this really shouldn't compile
|
||||||
reject bar(vfoo)
|
reject bar(vfoo)
|
||||||
|
|
||||||
# https://github.com/Araq/Nim/issues/517
|
# https://github.com/Araq/Nim/issues/517
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ AST b
|
||||||
20Test
|
20Test
|
||||||
20
|
20
|
||||||
'''
|
'''
|
||||||
|
disabled: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
msg: "int\nstring\nTBar[int]"
|
msg: "int\nstring\nTBar[int]"
|
||||||
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
|
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
|
||||||
|
disabled: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import typetraits
|
import typetraits
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "type mismatch: got (string) but expected 'ptr'"
|
errormsg: "type mismatch: got (string) but expected 'ptr'"
|
||||||
line: 20
|
line: 20
|
||||||
|
disabled: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import typetraits
|
import typetraits
|
||||||
|
|
|
||||||
11
tests/metatype/typedesc_as_value.nim
Normal file
11
tests/metatype/typedesc_as_value.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "'typedesc' metatype is not valid here; typed '=' instead of ':'?"
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
var x = int
|
||||||
|
|
||||||
|
echo x
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tests/reject/trecincb.nim"
|
file: "tests/reject/trecincb.nim"
|
||||||
line: 9
|
line: 9
|
||||||
errormsg: "recursive dependency: 'tests/module/trecincb.nim'"
|
errormsg: "recursive dependency: 'trecincb.nim'"
|
||||||
"""
|
"""
|
||||||
# Test recursive includes
|
# Test recursive includes
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "trecincb.nim"
|
file: "trecincb.nim"
|
||||||
line: 9
|
line: 9
|
||||||
errormsg: "recursive dependency: 'tests/module/trecincb.nim'"
|
errormsg: "recursive dependency: 'trecincb.nim'"
|
||||||
"""
|
"""
|
||||||
# Test recursive includes
|
# Test recursive includes
|
||||||
|
|
||||||
27
tests/objects/trefobjsyntax.nim
Normal file
27
tests/objects/trefobjsyntax.nim
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
discard """
|
||||||
|
output: '''wohoo
|
||||||
|
baz'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Test to ensure the popular 'ref T' syntax works everywhere
|
||||||
|
|
||||||
|
type
|
||||||
|
Foo = object
|
||||||
|
a, b: int
|
||||||
|
s: string
|
||||||
|
|
||||||
|
FooBar = object of RootObj
|
||||||
|
n, m: string
|
||||||
|
Baz = object of FooBar
|
||||||
|
|
||||||
|
proc invoke(a: ref Baz) =
|
||||||
|
echo "baz"
|
||||||
|
|
||||||
|
# check object construction:
|
||||||
|
let x = (ref Foo)(a: 0, b: 45, s: "wohoo")
|
||||||
|
echo x.s
|
||||||
|
|
||||||
|
var y: ref FooBar = (ref Baz)(n: "n", m: "m")
|
||||||
|
|
||||||
|
invoke((ref Baz)(y))
|
||||||
|
|
||||||
27
tests/objvariant/treassign.nim
Normal file
27
tests/objvariant/treassign.nim
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
discard """
|
||||||
|
output: "SUCCESS"
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
BasicNumber = object of RootObj
|
||||||
|
value: float32
|
||||||
|
RefChild* = ref object
|
||||||
|
curr*: TokenObject
|
||||||
|
Token* {.pure.} = enum
|
||||||
|
foo,
|
||||||
|
bar,
|
||||||
|
TokenObject = object
|
||||||
|
case kind*: Token
|
||||||
|
of Token.foo:
|
||||||
|
foo*: string
|
||||||
|
of Token.bar:
|
||||||
|
bar*: BasicNumber
|
||||||
|
|
||||||
|
|
||||||
|
var t = RefChild()
|
||||||
|
|
||||||
|
t.curr = TokenObject(kind: Token.bar, bar: BasicNumber(value: 12.34))
|
||||||
|
|
||||||
|
t.curr = TokenObject(kind: Token.foo, foo: "foo")
|
||||||
|
|
||||||
|
echo "SUCCESS"
|
||||||
|
|
@ -121,6 +121,7 @@ proc gcTests(r: var TResults, cat: Category, options: string) =
|
||||||
testSpec r, makeTest("tests/gc" / filename, options &
|
testSpec r, makeTest("tests/gc" / filename, options &
|
||||||
" -d:release --gc:markAndSweep", cat, actionRun)
|
" -d:release --gc:markAndSweep", cat, actionRun)
|
||||||
|
|
||||||
|
test "growobjcrash"
|
||||||
test "gcbench"
|
test "gcbench"
|
||||||
test "gcleak"
|
test "gcleak"
|
||||||
test "gcleak2"
|
test "gcleak2"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ discard """
|
||||||
# bug #1708
|
# bug #1708
|
||||||
let foo = {
|
let foo = {
|
||||||
"1" : (bar: @["1"]),
|
"1" : (bar: @["1"]),
|
||||||
"2" : (baz: @[])
|
"2" : (bar: @[])
|
||||||
}
|
}
|
||||||
|
|
||||||
# bug #871
|
# bug #871
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -4,8 +4,6 @@ version 0.10.4
|
||||||
- make 'nil' work for 'add' and 'len'
|
- make 'nil' work for 'add' and 'len'
|
||||||
- improve GC-unsafety warnings
|
- improve GC-unsafety warnings
|
||||||
- get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}'
|
- get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}'
|
||||||
- improve documentation (theindex!)
|
|
||||||
- fix the getUniqueType() bug
|
|
||||||
|
|
||||||
|
|
||||||
version 1.0
|
version 1.0
|
||||||
|
|
@ -67,7 +65,6 @@ version 0.9.x
|
||||||
- memory manager: add a measure of fragmentation
|
- memory manager: add a measure of fragmentation
|
||||||
- implement 'bits' pragmas
|
- implement 'bits' pragmas
|
||||||
- we need a magic thisModule symbol
|
- we need a magic thisModule symbol
|
||||||
- ensure (ref T)(a, b) works as a type conversion and type constructor
|
|
||||||
- optimize 'genericReset'; 'newException' leads to code bloat
|
- optimize 'genericReset'; 'newException' leads to code bloat
|
||||||
- The 'do' notation might be trimmed so that its only purpose is to pass
|
- The 'do' notation might be trimmed so that its only purpose is to pass
|
||||||
multiple multi line constructs to a macro.
|
multiple multi line constructs to a macro.
|
||||||
|
|
@ -96,4 +93,3 @@ CGEN
|
||||||
====
|
====
|
||||||
- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
|
- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC
|
||||||
- ``restrict`` pragma + backend support
|
- ``restrict`` pragma + backend support
|
||||||
- 'const' objects including case objects
|
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,7 @@ proc buildAddDoc(c: var TConfigData, destPath: string) =
|
||||||
# build additional documentation (without the index):
|
# build additional documentation (without the index):
|
||||||
var commands = newSeq[string](c.webdoc.len)
|
var commands = newSeq[string](c.webdoc.len)
|
||||||
for i, doc in pairs(c.webdoc):
|
for i, doc in pairs(c.webdoc):
|
||||||
commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# $#" %
|
commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$#/$# -o:$# $#" %
|
||||||
[c.nimArgs, c.gitRepo, c.gitCommit, doc.pathPart,
|
[c.nimArgs, c.gitRepo, c.gitCommit, doc.pathPart,
|
||||||
destPath / changeFileExt(splitFile(doc).name, "html"), doc]
|
destPath / changeFileExt(splitFile(doc).name, "html"), doc]
|
||||||
mexec(commands, c.numProcessors)
|
mexec(commands, c.numProcessors)
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,6 @@ news: news
|
||||||
[Ticker]
|
[Ticker]
|
||||||
file: ticker.txt
|
file: ticker.txt
|
||||||
|
|
||||||
[Quotations]
|
|
||||||
# Page: quote - Person
|
|
||||||
# Bad things will happen if you use multiple dashes here.
|
|
||||||
index: """Is it so bad, then, to be misunderstood? Pythagoras was misunderstood,
|
|
||||||
and Socrates, and Jesus, and Luther, and Copernicus, and Galileo, and Newton,
|
|
||||||
and every pure and wise spirit that ever took flesh. To be great is to be
|
|
||||||
misunderstood. - Ralph Waldo Emerson"""
|
|
||||||
documentation: """Incorrect documentation is often worse than no documentation.
|
|
||||||
- Bertrand Meyer"""
|
|
||||||
download: """There are two major products that come out of Berkeley: LSD and
|
|
||||||
UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson."""
|
|
||||||
learn: """Repetition renders the ridiculous reasonable. - Norman Wildberger"""
|
|
||||||
|
|
||||||
[Documentation]
|
[Documentation]
|
||||||
doc: "endb;intern;apis;lib;manual.txt;tut1;tut2;nimc;overview;filters"
|
doc: "endb;intern;apis;lib;manual.txt;tut1;tut2;nimc;overview;filters"
|
||||||
doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt"
|
doc: "tools;niminst;nimgrep;gc;estp;idetools;docgen;koch;backends.txt"
|
||||||
|
|
@ -61,7 +48,7 @@ srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor"
|
||||||
srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
||||||
srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes"
|
srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes"
|
||||||
srcdoc2: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics"
|
srcdoc2: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics"
|
||||||
srcdoc2: "impure/rdstdin;wrappers/sphinx"
|
srcdoc2: "impure/rdstdin"
|
||||||
srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
|
srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists"
|
||||||
srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/encodings"
|
srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/encodings"
|
||||||
srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies"
|
srcdoc2: "pure/events;pure/collections/sequtils;pure/cookies"
|
||||||
|
|
@ -71,19 +58,15 @@ srcdoc2: "pure/nimprof;pure/unittest;packages/docutils/highlite"
|
||||||
srcdoc2: "packages/docutils/rst;packages/docutils/rstast"
|
srcdoc2: "packages/docutils/rst;packages/docutils/rstast"
|
||||||
srcdoc2: "packages/docutils/rstgen;pure/logging;pure/asyncdispatch;pure/asyncnet"
|
srcdoc2: "packages/docutils/rstgen;pure/logging;pure/asyncdispatch;pure/asyncnet"
|
||||||
srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future"
|
srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future"
|
||||||
srcdoc2: "wrappers/expat;wrappers/readline/history"
|
srcdoc2: "pure/md5"
|
||||||
srcdoc2: "wrappers/libsvm.nim;wrappers/libuv"
|
srcdoc2: "posix/posix"
|
||||||
srcdoc2: "wrappers/zip/zlib;wrappers/zip/libzip"
|
|
||||||
srcdoc2: "pure/md5;wrappers/mysql;wrappers/iup"
|
|
||||||
srcdoc2: "posix/posix;wrappers/odbcsql"
|
|
||||||
srcdoc2: "wrappers/tre;wrappers/openssl;wrappers/pcre"
|
|
||||||
srcdoc2: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"
|
|
||||||
srcdoc2: "wrappers/readline/readline;wrappers/readline/rltypedefs"
|
|
||||||
srcdoc2: "wrappers/joyent_http_parser"
|
|
||||||
srcdoc2: "pure/fenv"
|
srcdoc2: "pure/fenv"
|
||||||
|
|
||||||
webdoc: "pure/md5;wrappers/mysql;wrappers/iup"
|
; Note: everything under 'webdoc' doesn't get listed in the index, so wrappers
|
||||||
webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc"
|
; should live here
|
||||||
|
|
||||||
|
webdoc: "wrappers/mysql;wrappers/iup;wrappers/sphinx"
|
||||||
|
webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc;wrappers/odbcsql"
|
||||||
webdoc: "wrappers/expat;wrappers/pcre"
|
webdoc: "wrappers/expat;wrappers/pcre"
|
||||||
webdoc: "wrappers/tre;wrappers/openssl"
|
webdoc: "wrappers/tre;wrappers/openssl"
|
||||||
webdoc: "wrappers/libuv;wrappers/joyent_http_parser"
|
webdoc: "wrappers/libuv;wrappers/joyent_http_parser"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue