summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2022-10-05 16:35:40 +0800
committerGitHub <noreply@github.com>2022-10-05 10:35:40 +0200
commit3e2b30879c31d386b5da0043f6a2604d9c0d7bb4 (patch)
treecec0ff15f38fe6f88c31d2298ff35b94966b8f3c
parent2dec69fe5aa67d4089bf674c25097cc3342b5284 (diff)
downloadNim-3e2b30879c31d386b5da0043f6a2604d9c0d7bb4.tar.gz
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
-rw-r--r--compiler/semmagic.nim59
-rw-r--r--tests/arc/t19231.nim18
2 files changed, 46 insertions, 31 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 5cfde46f0..f815c7059 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -404,18 +404,14 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym; info: TLineInfo): PSym
   # Replace nkDerefExpr by nkHiddenDeref
   # nkDeref is for 'ref T':  x[].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)
     if sameTypeOrNil(n.typ, old):
       result.typ = fresh
-    if n.kind == nkSym:
-      if n.sym == oldParam:
-        result.sym = newParam
-      elif n.sym.owner == orig:
-        result.sym = copySym(n.sym, nextSymId c.idgen)
-        result.sym.owner = procSym
+    if n.kind == nkSym and n.sym == oldParam:
+      result.sym = newParam
     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):
     #  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)
   newParam.typ = newParamType
   # 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:
   result.typ = newProcType(result.info, nextTypeId c.idgen, result)
   result.typ.addParam newParam
@@ -492,28 +488,29 @@ proc semNewFinalize(c: PContext; n: PNode): PNode =
           getAttachedOp(c.graph, t, attachedDestructor).owner == fin:
         discard "already turned this one into a finalizer"
       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 selfSymNode = newSymNode(copySym(fin.ast[paramsPos][1][0].sym, nextSymId c.idgen))
-          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,
-                    newTree(nkIdentDefs, selfSymNode, fin.ast[paramsPos][1][1], c.graph.emptyNode)
-                    ),
-            name = newSymNode(wrapperSym), pattern = c.graph.emptyNode,
-            genericParams = c.graph.emptyNode, pragmas = c.graph.emptyNode, exceptions = c.graph.emptyNode), {})
-          var transFormedSym = turnFinalizerIntoDestructor(c, wrapperSym, wrapper.info)
-          transFormedSym.owner = fin
-          if c.config.backend == backendCpp or sfCompileToCpp in c.module.flags:
-            let origParamType = transFormedSym.ast[bodyPos][1].typ
-            let selfSymbolType = makePtrType(c, origParamType.skipTypes(abstractPtrs))
-            let selfPtr = newNodeI(nkHiddenAddr, transFormedSym.ast[bodyPos][1].info)
-            selfPtr.add transFormedSym.ast[bodyPos][1]
-            selfPtr.typ = selfSymbolType
-            transFormedSym.ast[bodyPos][1] = c.semExpr(c, selfPtr)
-          bindTypeHook(c, transFormedSym, n, attachedDestructor)
-        else:
-          bindTypeHook(c, turnFinalizerIntoDestructor(c, fin, n.info), n, attachedDestructor)
+        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))
+        selfSymNode.typ = fin.typ[1]
+        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,
+                  newTree(nkIdentDefs, selfSymNode, newNodeIT(nkType,
+                  fin.ast[paramsPos][1][1].info, fin.typ[1]), c.graph.emptyNode)
+                  ),
+          name = newSymNode(wrapperSym), pattern = fin.ast[patternPos],
+          genericParams = fin.ast[genericParamsPos], pragmas = fin.ast[pragmasPos], exceptions = fin.ast[miscPos]), {})
+
+        var transFormedSym = turnFinalizerIntoDestructor(c, wrapperSym, wrapper.info)
+        transFormedSym.owner = fin
+        if c.config.backend == backendCpp or sfCompileToCpp in c.module.flags:
+          let origParamType = transFormedSym.ast[bodyPos][1].typ
+          let selfSymbolType = makePtrType(c, origParamType.skipTypes(abstractPtrs))
+          let selfPtr = newNodeI(nkHiddenAddr, transFormedSym.ast[bodyPos][1].info)
+          selfPtr.add transFormedSym.ast[bodyPos][1]
+          selfPtr.typ = selfSymbolType
+          transFormedSym.ast[bodyPos][1] = c.semExpr(c, selfPtr)
+        bindTypeHook(c, transFormedSym, n, attachedDestructor)
   result = addDefaultFieldForNew(c, n)
 
 proc semPrivateAccess(c: PContext, n: PNode): PNode =
diff --git a/tests/arc/t19231.nim b/tests/arc/t19231.nim
new file mode 100644
index 000000000..40fcf277c
--- /dev/null
+++ b/tests/arc/t19231.nim
@@ -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