This commit is contained in:
Andreas Rumpf
2021-06-25 06:22:52 +02:00
committed by GitHub
parent 6be8a66833
commit 0d194cdbf9
2 changed files with 74 additions and 25 deletions

View File

@@ -416,7 +416,6 @@ proc allRoots(n: PNode; result: var seq[(PSym, int)]; level: int) =
proc destMightOwn(c: var Partitions; dest: var VarIndex; n: PNode) =
## Analyse if 'n' is an expression that owns the data, if so mark 'dest'
## with 'ownsData'.
if n.typ == nil: return
case n.kind
of nkEmpty, nkCharLit..nkNilLit:
# primitive literals including the empty are harmless:
@@ -475,30 +474,31 @@ proc destMightOwn(c: var Partitions; dest: var VarIndex; n: PNode) =
destMightOwn(c, dest, n[0])
of nkCallKinds:
if hasDestructor(n.typ):
# calls do construct, what we construct must be destroyed,
# so dest cannot be a cursor:
dest.flags.incl ownsData
elif n.typ.kind in {tyLent, tyVar}:
# we know the result is derived from the first argument:
var roots: seq[(PSym, int)]
allRoots(n[1], roots, RootEscapes)
for r in roots:
connect(c, dest.sym, r[0], n[1].info)
if n.typ != nil:
if hasDestructor(n.typ):
# calls do construct, what we construct must be destroyed,
# so dest cannot be a cursor:
dest.flags.incl ownsData
elif n.typ.kind in {tyLent, tyVar}:
# we know the result is derived from the first argument:
var roots: seq[(PSym, int)]
allRoots(n[1], roots, RootEscapes)
for r in roots:
connect(c, dest.sym, r[0], n[1].info)
else:
let magic = if n[0].kind == nkSym: n[0].sym.magic else: mNone
# this list is subtle, we try to answer the question if after 'dest = f(src)'
# there is a connection betwen 'src' and 'dest' so that mutations to 'src'
# also reflect 'dest':
if magic in {mNone, mMove, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mArrToSeq}:
for i in 1..<n.len:
# we always have to assume a 'select(...)' like mechanism.
# But at least we do filter out simple POD types from the
# list of dependencies via the 'hasDestructor' check for
# the root's symbol.
if hasDestructor(n[i].typ.skipTypes({tyVar, tySink, tyLent, tyGenericInst, tyAlias})):
destMightOwn(c, dest, n[i])
else:
let magic = if n[0].kind == nkSym: n[0].sym.magic else: mNone
# this list is subtle, we try to answer the question if after 'dest = f(src)'
# there is a connection betwen 'src' and 'dest' so that mutations to 'src'
# also reflect 'dest':
if magic in {mNone, mMove, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mArrToSeq}:
for i in 1..<n.len:
# we always have to assume a 'select(...)' like mechanism.
# But at least we do filter out simple POD types from the
# list of dependencies via the 'hasDestructor' check for
# the root's symbol.
if hasDestructor(n[i].typ.skipTypes({tyVar, tySink, tyLent, tyGenericInst, tyAlias})):
destMightOwn(c, dest, n[i])
else:
# something we cannot handle:

View File

@@ -8,7 +8,7 @@ doing shady stuff...
192.168.0.1
192.168.0.1
192.168.0.1'''
cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope $file'''
cmd: '''nim c --gc:arc --expandArc:newTarget --expandArc:delete --expandArc:p1 --expandArc:tt --hint:Performance:off --assertions:off --expandArc:extractConfig --expandArc:mergeShadowScope --expandArc:check $file'''
nimout: '''--expandArc: newTarget
var
@@ -127,6 +127,36 @@ block :tmp:
:tmpD
inc(i, 1)
`=destroy`(shadowScope)
-- end of expandArc ------------------------
--expandArc: check
var par
this.isValid = fileExists(this.value)
if dirExists(this.value):
var :tmpD
par = (dir:
wasMoved(:tmpD)
`=copy`(:tmpD, this.value)
:tmpD, front: "") else:
var
:tmpD_1
:tmpD_2
:tmpD_3
par = (dir_1: parentDir(this.value), front_1:
wasMoved(:tmpD_1)
`=copy`(:tmpD_1,
:tmpD_3 = splitPath do:
wasMoved(:tmpD_2)
`=copy`(:tmpD_2, this.value)
:tmpD_2
:tmpD_3.tail)
:tmpD_1)
`=destroy`(:tmpD_3)
if dirExists(par.dir):
`=sink`(this.matchDirs, getSubDirs(par.dir, par.front))
else:
`=sink`(this.matchDirs, [])
`=destroy`(par)
-- end of expandArc ------------------------'''
"""
@@ -322,3 +352,22 @@ proc mergeShadowScope*(c: PContext) =
c.addInterfaceDecl(sym)
mergeShadowScope(PContext(currentScope: Scope(parent: Scope())))
type
Foo = ref object
isValid*: bool
value*: string
matchDirs*: seq[string]
proc getSubDirs(parent, front: string): seq[string] = @[]
method check(this: Foo) {.base.} =
this.isValid = fileExists(this.value)
let par = if dirExists(this.value): (dir: this.value, front: "")
else: (dir: parentDir(this.value), front: splitPath(this.value).tail)
if dirExists(par.dir):
this.matchDirs = getSubDirs(par.dir, par.front)
else:
this.matchDirs = @[]
check(Foo())