fixes #19231; newFinalize doesn't work with ORC (#20291)

* fixes #19231; newFinalize doesn't work with ORC

first make it pass tests

* remove the tables dep

creates a binding for finalized procs in order to handle the same symbols. It used to wrongly generat a new symbol id for the same symbol as the encountered one before

* refactor and revert #14257

* de indentation

* fixes tests; uses instantiated types
This commit is contained in:
ringabout 2022-10-05 16:35:40 +08:00 • committed by GitHub
commit 3e2b30879c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 31 deletions

View file

@ -404,18 +404,14 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym; info: TLineInfo): PSym
# Replace nkDerefExpr by nkHiddenDeref # Replace nkDerefExpr by nkHiddenDeref
# nkDeref is for 'ref T': x[].field # nkDeref is for 'ref T': x[].field
# nkHiddenDeref is for 'var T': x<hidden deref [] here>.field # nkHiddenDeref is for 'var T': x<hidden deref [] here>.field
proc transform(c: PContext; procSym: PSym; n: PNode; old, fresh: PType; oldParam, newParam: PSym): PNode = proc transform(c: PContext; n: PNode; old, fresh: PType; oldParam, newParam: PSym): PNode =
result = shallowCopy(n) result = shallowCopy(n)
if sameTypeOrNil(n.typ, old): if sameTypeOrNil(n.typ, old):
result.typ = fresh result.typ = fresh
if n.kind == nkSym: if n.kind == nkSym and n.sym == oldParam:
if n.sym == oldParam: result.sym = newParam
result.sym = newParam
elif n.sym.owner == orig:
result.sym = copySym(n.sym, nextSymId c.idgen)
result.sym.owner = procSym
for i in 0 ..< safeLen(n): for i in 0 ..< safeLen(n):
result[i] = transform(c, procSym, n[i], old, fresh, oldParam, newParam) result[i] = transform(c, n[i], old, fresh, oldParam, newParam)
#if n.kind == nkDerefExpr and sameType(n[0].typ, old): #if n.kind == nkDerefExpr and sameType(n[0].typ, old):
# result = # result =
@ -429,7 +425,7 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym; info: TLineInfo): PSym
let newParam = newSym(skParam, oldParam.name, nextSymId c.idgen, result, result.info) let newParam = newSym(skParam, oldParam.name, nextSymId c.idgen, result, result.info)
newParam.typ = newParamType newParam.typ = newParamType
# proc body: # proc body:
result.ast = transform(c, result, orig.ast, origParamType, newParamType, oldParam, newParam) result.ast = transform(c, orig.ast, origParamType, newParamType, oldParam, newParam)
# proc signature: # proc signature:
result.typ = newProcType(result.info, nextTypeId c.idgen, result) result.typ = newProcType(result.info, nextTypeId c.idgen, result)
result.typ.addParam newParam result.typ.addParam newParam
@ -492,28 +488,29 @@ proc semNewFinalize(c: PContext; n: PNode): PNode =
getAttachedOp(c.graph, t, attachedDestructor).owner == fin: getAttachedOp(c.graph, t, attachedDestructor).owner == fin:
discard "already turned this one into a finalizer" discard "already turned this one into a finalizer"
else: else:
if sfForward in fin.flags: let wrapperSym = newSym(skProc, getIdent(c.graph.cache, fin.name.s & "FinalizerWrapper"), nextSymId c.idgen, fin.owner, fin.info)
let wrapperSym = newSym(skProc, getIdent(c.graph.cache, fin.name.s & "FinalizerWrapper"), nextSymId c.idgen, fin.owner, fin.info) let selfSymNode = newSymNode(copySym(fin.ast[paramsPos][1][0].sym, nextSymId c.idgen))
let selfSymNode = newSymNode(copySym(fin.ast[paramsPos][1][0].sym, nextSymId c.idgen)) selfSymNode.typ = fin.typ[1]
wrapperSym.flags.incl sfUsed wrapperSym.flags.incl sfUsed
let wrapper = c.semExpr(c, newProcNode(nkProcDef, fin.info, body = newTree(nkCall, newSymNode(fin), selfSymNode),
params = nkFormalParams.newTree(c.graph.emptyNode, let wrapper = c.semExpr(c, newProcNode(nkProcDef, fin.info, body = newTree(nkCall, newSymNode(fin), selfSymNode),
newTree(nkIdentDefs, selfSymNode, fin.ast[paramsPos][1][1], c.graph.emptyNode) params = nkFormalParams.newTree(c.graph.emptyNode,
), newTree(nkIdentDefs, selfSymNode, newNodeIT(nkType,
name = newSymNode(wrapperSym), pattern = c.graph.emptyNode, fin.ast[paramsPos][1][1].info, fin.typ[1]), c.graph.emptyNode)
genericParams = c.graph.emptyNode, pragmas = c.graph.emptyNode, exceptions = c.graph.emptyNode), {}) ),
var transFormedSym = turnFinalizerIntoDestructor(c, wrapperSym, wrapper.info) name = newSymNode(wrapperSym), pattern = fin.ast[patternPos],
transFormedSym.owner = fin genericParams = fin.ast[genericParamsPos], pragmas = fin.ast[pragmasPos], exceptions = fin.ast[miscPos]), {})
if c.config.backend == backendCpp or sfCompileToCpp in c.module.flags:
let origParamType = transFormedSym.ast[bodyPos][1].typ var transFormedSym = turnFinalizerIntoDestructor(c, wrapperSym, wrapper.info)
let selfSymbolType = makePtrType(c, origParamType.skipTypes(abstractPtrs)) transFormedSym.owner = fin
let selfPtr = newNodeI(nkHiddenAddr, transFormedSym.ast[bodyPos][1].info) if c.config.backend == backendCpp or sfCompileToCpp in c.module.flags:
selfPtr.add transFormedSym.ast[bodyPos][1] let origParamType = transFormedSym.ast[bodyPos][1].typ
selfPtr.typ = selfSymbolType let selfSymbolType = makePtrType(c, origParamType.skipTypes(abstractPtrs))
transFormedSym.ast[bodyPos][1] = c.semExpr(c, selfPtr) let selfPtr = newNodeI(nkHiddenAddr, transFormedSym.ast[bodyPos][1].info)
bindTypeHook(c, transFormedSym, n, attachedDestructor) selfPtr.add transFormedSym.ast[bodyPos][1]
else: selfPtr.typ = selfSymbolType
bindTypeHook(c, turnFinalizerIntoDestructor(c, fin, n.info), n, attachedDestructor) transFormedSym.ast[bodyPos][1] = c.semExpr(c, selfPtr)
bindTypeHook(c, transFormedSym, n, attachedDestructor)
result = addDefaultFieldForNew(c, n) result = addDefaultFieldForNew(c, n)
proc semPrivateAccess(c: PContext, n: PNode): PNode = proc semPrivateAccess(c: PContext, n: PNode): PNode =

18
tests/arc/t19231.nim Normal file
View file

@ -0,0 +1,18 @@
discard """
matrix: "--mm:orc"
targets: "c cpp"
"""
type
Game* = ref object
proc free*(game: Game) =
var mixNumOpened:cint = 0
for i in 0..<mixNumOpened:
mixNumOpened -= 1
proc newGame*(): Game =
new result, free
var
game*: Game