diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-11-02 00:39:04 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-11-02 00:39:04 +0100 |
commit | 44a27ccfe1cd56f2e77979eba4814d94eec47b41 (patch) | |
tree | a145b167692c3572b4cf19bb2b50e2d8ec9472f7 | |
parent | 7a4d066102c3fdacaebb093699024693033742b1 (diff) | |
download | Nim-44a27ccfe1cd56f2e77979eba4814d94eec47b41.tar.gz |
--gc:destructors: simple closures work
-rw-r--r-- | compiler/ccgexprs.nim | 2 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 4 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 5 | ||||
-rw-r--r-- | compiler/lambdalifting.nim | 22 |
4 files changed, 20 insertions, 13 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index f6cf799bd..1d9d0aca6 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1193,8 +1193,6 @@ proc genDefault(p: BProc; n: PNode; d: var TLoc) = if d.k == locNone: getTemp(p, n.typ, d, needsInit=true) else: resetLoc(p, d) -proc trivialDestructor(s: PSym): bool {.inline.} = s.ast[bodyPos].len == 0 - proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = var sizeExpr = sizeExpr let typ = a.t diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index de1f0e497..a867c58c1 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -1275,6 +1275,8 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope = it = it.sons[0] result = makeCString(res) +proc trivialDestructor(s: PSym): bool {.inline.} = s.ast[bodyPos].len == 0 + proc genObjectInfoV2(m: BModule, t, origType: PType, name: Rope; info: TLineInfo) = assert t.kind == tyObject if incompleteType(t): @@ -1282,7 +1284,7 @@ proc genObjectInfoV2(m: BModule, t, origType: PType, name: Rope; info: TLineInfo typeToString(t)) var d: Rope - if t.destructor != nil: + if t.destructor != nil and not trivialDestructor(t.destructor): # the prototype of a destructor is ``=destroy(x: var T)`` and that of a # finalizer is: ``proc (x: ref T) {.nimcall.}``. We need to check the calling # convention at least: diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index f1823bf64..78ab2daef 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -173,6 +173,9 @@ proc genOp(c: Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode = elif op.ast[genericParamsPos].kind != nkEmpty: globalError(c.graph.config, dest.info, "internal error: '" & AttachedOpToStr[kind] & "' operator is generic") + dbg: + if kind == attachedDestructor: + echo "destructor is ", op.id, " ", op.ast if sfError in op.flags: checkForErrorPragma(c, t, ri, AttachedOpToStr[kind]) let addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ)) addrExp.add(dest) @@ -681,4 +684,4 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = result.add body dbg: echo ">---------transformed-to--------->" - echo result + echo renderTree(result, {renderIds}) diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 4a2d40ec7..9f1d29ec6 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -233,6 +233,10 @@ proc liftingHarmful(conf: ConfigRef; owner: PSym): bool {.inline.} = let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro result = conf.cmd == cmdCompileToJS and not isCompileTime +proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo) = + createTypeBoundOps(g, nil, refType.lastSon, info) + createTypeBoundOps(g, nil, refType, info) + proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode = # transforms (iter) to (let env = newClosure[iter](); (iter, env)) if liftingHarmful(g.config, owner): return n @@ -257,8 +261,8 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode = result.add(v) # add 'new' statement: result.add newCall(getSysSym(g, n.info, "internalNew"), env) - if optOwnedRefs in g.config.globalOptions: - createTypeBoundOps(g, nil, env.typ, n.info) + if g.config.selectedGC in {gcHooks, gcDestructors}: + createTypeBoundOpsLL(g, env.typ, n.info) result.add makeClosure(g, iter, env, n.info) proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode = @@ -586,7 +590,7 @@ proc rawClosureCreation(owner: PSym; let env2 = copyTree(env) env2.typ = unowned.typ result.add newAsgnStmt(unowned, env2, env.info) - createTypeBoundOps(d.graph, nil, unowned.typ, env.info) + createTypeBoundOpsLL(d.graph, unowned.typ, env.info) # add assignment statements for captured parameters: for i in 1..<owner.typ.n.len: @@ -609,8 +613,8 @@ proc rawClosureCreation(owner: PSym; localError(d.graph.config, env.info, "internal error: cannot create up reference") # we are not in the sem'check phase anymore! so pass 'nil' for the PContext # and hope for the best: - if optOwnedRefs in d.graph.config.globalOptions: - createTypeBoundOps(d.graph, nil, env.typ, owner.info) + if d.graph.config.selectedGC in {gcHooks, gcDestructors}: + createTypeBoundOpsLL(d.graph, env.typ, owner.info) proc finishClosureCreation(owner: PSym; d: DetectionPass; c: LiftingPass; info: TLineInfo; res: PNode) = @@ -638,8 +642,8 @@ proc closureCreationForIter(iter: PNode; addVar(vs, vnode) result.add(vs) result.add(newCall(getSysSym(d.graph, iter.info, "internalNew"), vnode)) - if optOwnedRefs in d.graph.config.globalOptions: - createTypeBoundOps(d.graph, nil, vnode.typ, iter.info) + if d.graph.config.selectedGC in {gcHooks, gcDestructors}: + createTypeBoundOpsLL(d.graph, vnode.typ, iter.info) let upField = lookupInRecord(v.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName)) if upField != nil: @@ -924,8 +928,8 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode = result.add(v) # add 'new' statement: result.add(newCall(getSysSym(g, env.info, "internalNew"), env.newSymNode)) - if optOwnedRefs in g.config.globalOptions: - createTypeBoundOps(g, nil, env.typ, body.info) + if g.config.selectedGC in {gcHooks, gcDestructors}: + createTypeBoundOpsLL(g, env.typ, body.info) elif op.kind == nkStmtListExpr: let closure = op.lastSon |