diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-07-06 17:14:42 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-06 11:14:42 +0200 |
commit | dfa0d2569e772d6fc4568796db03f65dc2e94771 (patch) | |
tree | 02bae53201fd7c0531b888c9695376877a0261b3 | |
parent | 7616e6ee2b48a3c3504684f3324a42e95bd73790 (diff) | |
download | Nim-dfa0d2569e772d6fc4568796db03f65dc2e94771.tar.gz |
alternative to #22219; adds a pointer wrapper for T destructor (#22225)
* alternative to #22219; adds a pointer wrapper for T destructor * clean up and add comments * Update compiler/ccgtypes.nim * tidy up * fixes comments * fixes cpp * fixes cpp
-rw-r--r-- | compiler/ccgexprs.nim | 4 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 55 |
2 files changed, 53 insertions, 6 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index e2498b57b..c585290cd 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1919,10 +1919,6 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = else: putIntoDest(p, d, e, rope(lengthOrd(p.config, typ))) else: internalError(p.config, e.info, "genArrayLen()") -proc makePtrType(baseType: PType; idgen: IdGenerator): PType = - result = newType(tyPtr, nextTypeId idgen, baseType.owner) - addSonSkipIntLit(result, baseType, idgen) - proc makeAddr(n: PNode; idgen: IdGenerator): PNode = if n.kind == nkHiddenAddr: result = n diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index f808fa93e..9f4b7aa7c 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1517,6 +1517,51 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope = proc isTrivialProc(g: ModuleGraph; s: PSym): bool {.inline.} = getBody(g, s).len == 0 +proc makePtrType(baseType: PType; idgen: IdGenerator): PType = + result = newType(tyPtr, nextTypeId idgen, baseType.owner) + addSonSkipIntLit(result, baseType, idgen) + +proc generateRttiDestructor(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp; + info: TLineInfo; idgen: IdGenerator; theProc: PSym): PSym = + # the wrapper is roughly like: + # proc rttiDestroy(x: pointer) = + # `=destroy`(cast[ptr T](x)[]) + let procname = getIdent(g.cache, "rttiDestroy") + result = newSym(skProc, procname, idgen, owner, info) + let dest = newSym(skParam, getIdent(g.cache, "dest"), idgen, result, info) + + dest.typ = getSysType(g, info, tyPointer) + + result.typ = newProcType(info, nextTypeId(idgen), owner) + result.typ.addParam dest + + var n = newNodeI(nkProcDef, info, bodyPos+1) + for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info) + n[namePos] = newSymNode(result) + n[paramsPos] = result.typ.n + let body = newNodeI(nkStmtList, info) + let castType = makePtrType(typ, idgen) + if theProc.typ[1].kind != tyVar: + body.add newTreeI(nkCall, info, newSymNode(theProc), newDeref(newTreeIT( + nkCast, info, castType, newNodeIT(nkType, info, castType), + newSymNode(dest) + )) + ) + else: + let addrOf = newNodeIT(nkAddr, info, theProc.typ[1]) + addrOf.add newDeref(newTreeIT( + nkCast, info, castType, newNodeIT(nkType, info, castType), + newSymNode(dest) + )) + body.add newTreeI(nkCall, info, newSymNode(theProc), + addrOf + ) + n[bodyPos] = body + result.ast = n + + incl result.flags, sfFromGeneric + incl result.flags, sfGeneratedOp + proc genHook(m: BModule; t: PType; info: TLineInfo; op: TTypeAttachedOp; result: var Rope) = let theProc = getAttachedOp(m.g.graph, t, op) if theProc != nil and not isTrivialProc(m.g.graph, theProc): @@ -1527,8 +1572,14 @@ proc genHook(m: BModule; t: PType; info: TLineInfo; op: TTypeAttachedOp; result: localError(m.config, info, theProc.name.s & " needs to have the 'nimcall' calling convention") - genProc(m, theProc) - result.add theProc.loc.r + if op == attachedDestructor: + let wrapper = generateRttiDestructor(m.g.graph, t, theProc.owner, attachedDestructor, + theProc.info, m.idgen, theProc) + genProc(m, wrapper) + result.add wrapper.loc.r + else: + genProc(m, theProc) + result.add theProc.loc.r when false: if not canFormAcycle(m.g.graph, t) and op == attachedTrace: |