gc:destructors: progress

This commit is contained in:
Andreas Rumpf
2019-02-28 22:39:15 +01:00
parent 9563be37d3
commit 728ff1004a
6 changed files with 85 additions and 2 deletions

View File

@@ -306,7 +306,9 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
resetIdTable(cl.symMap)
resetIdTable(cl.localCache)
cl.isReturnType = true
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
cl.isReturnType = false
result.n.sons[0] = originalParams[0].copyTree
if result.sons[0] != nil:
propagateToOwner(result, result.sons[0])

View File

@@ -481,6 +481,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
if typ == nil: continue
typeAllowedCheck(c.config, a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {})
liftTypeBoundOps(c.graph, typ, a.info)
instAllTypeBoundOp(c, a.info)
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
if a.kind == nkVarTuple:
if tup.kind != tyTuple:

View File

@@ -88,6 +88,7 @@ type
allowMetaTypes*: bool # allow types such as seq[Number]
# i.e. the result contains unresolved generics
skipTypedesc*: bool # wether we should skip typeDescs
isReturnType*: bool
owner*: PSym # where this instantiation comes from
recursionLimit: int
@@ -594,6 +595,21 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
eraseVoidParams(result)
skipIntLiteralParams(result)
of tySequence:
if cl.isReturnType and cl.c.config.selectedGc == gcDestructors and result.destructor.isNil and
result[0].kind != tyEmpty:
let s = cl.c.graph.sysTypes[tySequence]
var old = copyType(s, s.owner, keepId=false)
# Remove the 'T' parameter from tySequence:
old.sons.setLen 0
old.n = nil
old.flags = {tfHasAsgn}
old.addSonSkipIntLit result[0]
result.destructor = old.destructor
result.assignment = old.assignment
result.sink = old.sink
cl.c.typesWithOps.add((result, old))
else: discard
else:
# If this type doesn't refer to a generic type we may still want to run it

View File

@@ -118,7 +118,7 @@ proc shrink*[T](x: var seq[T]; newLen: Natural) =
when not supportsCopyMem(T):
for i in countdown(x.len - 1, newLen - 1):
`=destroy`(x[i])
# XXX This is wrong for const seqs that were moved into 'x'!
cast[ptr NimSeqV2[T]](addr x).len = newLen
proc grow*[T](x: var seq[T]; newLen: Natural; value: T) =

View File

@@ -164,6 +164,7 @@ proc mnewString(len: int): NimStringV2 {.compilerProc.} =
proc setLengthStrV2(s: var NimStringV2, newLen: int) {.compilerRtl.} =
if newLen > s.len:
prepareAdd(s, newLen - s.len)
# XXX This is wrong for const strings that got moved into 's'!
s.len = newLen
# this also only works because the destructor
# looks at s.p and not s.len

View File

@@ -3,7 +3,7 @@ discard """
output: '''hi
ho
ha
1 1'''
7 7'''
"""
import allocators
@@ -21,6 +21,69 @@ const
for t in test:
echo t
type
InterpolatedKind* = enum
ikStr, ## ``str`` part of the interpolated string
ikDollar, ## escaped ``$`` part of the interpolated string
ikVar, ## ``var`` part of the interpolated string
ikExpr ## ``expr`` part of the interpolated string
iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
value: string] =
var i = 0
var kind: InterpolatedKind
while true:
var j = i
if j < s.len and s[j] == '$':
if j+1 < s.len and s[j+1] == '{':
inc j, 2
var nesting = 0
block curlies:
while j < s.len:
case s[j]
of '{': inc nesting
of '}':
if nesting == 0:
inc j
break curlies
dec nesting
else: discard
inc j
raise newException(ValueError,
"Expected closing '}': " & substr(s, i, s.high))
inc i, 2 # skip ${
kind = ikExpr
elif j+1 < s.len and s[j+1] in {'A'..'Z', 'a'..'z', '_'}:
inc j, 2
while j < s.len and s[j] in {'A'..'Z', 'a'..'z', '0'..'9', '_'}: inc(j)
inc i # skip $
kind = ikVar
elif j+1 < s.len and s[j+1] == '$':
inc j, 2
inc i # skip $
kind = ikDollar
else:
raise newException(ValueError,
"Unable to parse a varible name at " & substr(s, i, s.high))
else:
while j < s.len and s[j] != '$': inc j
kind = ikStr
if j > i:
# do not copy the trailing } for ikExpr:
yield (kind, substr(s, i, j-1-ord(kind == ikExpr)))
else:
break
i = j
let input = "$test{} $this is ${an{ example}} "
let expected = @[(ikVar, "test"), (ikStr, "{} "), (ikVar, "this"),
(ikStr, " is "), (ikExpr, "an{ example}"), (ikStr, " ")]
var i = 0
for s in interpolatedFragments(input):
doAssert s == expected[i]
inc i
#echo s
let (a, d) = allocCounters()
cprintf("%ld %ld\n", a, d)