--gc:destructors: simple closures work
This commit is contained in:
parent
7a4d066102
commit
44a27ccfe1
4 changed files with 20 additions and 13 deletions
|
|
@ -1193,8 +1193,6 @@ proc genDefault(p: BProc; n: PNode; d: var TLoc) =
|
||||||
if d.k == locNone: getTemp(p, n.typ, d, needsInit=true)
|
if d.k == locNone: getTemp(p, n.typ, d, needsInit=true)
|
||||||
else: resetLoc(p, d)
|
else: resetLoc(p, d)
|
||||||
|
|
||||||
proc trivialDestructor(s: PSym): bool {.inline.} = s.ast[bodyPos].len == 0
|
|
||||||
|
|
||||||
proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
|
||||||
var sizeExpr = sizeExpr
|
var sizeExpr = sizeExpr
|
||||||
let typ = a.t
|
let typ = a.t
|
||||||
|
|
|
||||||
|
|
@ -1275,6 +1275,8 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope =
|
||||||
it = it.sons[0]
|
it = it.sons[0]
|
||||||
result = makeCString(res)
|
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) =
|
proc genObjectInfoV2(m: BModule, t, origType: PType, name: Rope; info: TLineInfo) =
|
||||||
assert t.kind == tyObject
|
assert t.kind == tyObject
|
||||||
if incompleteType(t):
|
if incompleteType(t):
|
||||||
|
|
@ -1282,7 +1284,7 @@ proc genObjectInfoV2(m: BModule, t, origType: PType, name: Rope; info: TLineInfo
|
||||||
typeToString(t))
|
typeToString(t))
|
||||||
|
|
||||||
var d: Rope
|
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
|
# 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
|
# finalizer is: ``proc (x: ref T) {.nimcall.}``. We need to check the calling
|
||||||
# convention at least:
|
# convention at least:
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,9 @@ proc genOp(c: Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode =
|
||||||
elif op.ast[genericParamsPos].kind != nkEmpty:
|
elif op.ast[genericParamsPos].kind != nkEmpty:
|
||||||
globalError(c.graph.config, dest.info, "internal error: '" & AttachedOpToStr[kind] &
|
globalError(c.graph.config, dest.info, "internal error: '" & AttachedOpToStr[kind] &
|
||||||
"' operator is generic")
|
"' 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])
|
if sfError in op.flags: checkForErrorPragma(c, t, ri, AttachedOpToStr[kind])
|
||||||
let addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ))
|
let addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ))
|
||||||
addrExp.add(dest)
|
addrExp.add(dest)
|
||||||
|
|
@ -681,4 +684,4 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||||
result.add body
|
result.add body
|
||||||
dbg:
|
dbg:
|
||||||
echo ">---------transformed-to--------->"
|
echo ">---------transformed-to--------->"
|
||||||
echo result
|
echo renderTree(result, {renderIds})
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,10 @@ proc liftingHarmful(conf: ConfigRef; owner: PSym): bool {.inline.} =
|
||||||
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
|
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
|
||||||
result = conf.cmd == cmdCompileToJS and not isCompileTime
|
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 =
|
proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||||
if liftingHarmful(g.config, owner): return n
|
if liftingHarmful(g.config, owner): return n
|
||||||
|
|
@ -257,8 +261,8 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||||
result.add(v)
|
result.add(v)
|
||||||
# add 'new' statement:
|
# add 'new' statement:
|
||||||
result.add newCall(getSysSym(g, n.info, "internalNew"), env)
|
result.add newCall(getSysSym(g, n.info, "internalNew"), env)
|
||||||
if optOwnedRefs in g.config.globalOptions:
|
if g.config.selectedGC in {gcHooks, gcDestructors}:
|
||||||
createTypeBoundOps(g, nil, env.typ, n.info)
|
createTypeBoundOpsLL(g, env.typ, n.info)
|
||||||
result.add makeClosure(g, iter, env, n.info)
|
result.add makeClosure(g, iter, env, n.info)
|
||||||
|
|
||||||
proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode =
|
proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode =
|
||||||
|
|
@ -586,7 +590,7 @@ proc rawClosureCreation(owner: PSym;
|
||||||
let env2 = copyTree(env)
|
let env2 = copyTree(env)
|
||||||
env2.typ = unowned.typ
|
env2.typ = unowned.typ
|
||||||
result.add newAsgnStmt(unowned, env2, env.info)
|
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:
|
# add assignment statements for captured parameters:
|
||||||
for i in 1..<owner.typ.n.len:
|
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")
|
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
|
# we are not in the sem'check phase anymore! so pass 'nil' for the PContext
|
||||||
# and hope for the best:
|
# and hope for the best:
|
||||||
if optOwnedRefs in d.graph.config.globalOptions:
|
if d.graph.config.selectedGC in {gcHooks, gcDestructors}:
|
||||||
createTypeBoundOps(d.graph, nil, env.typ, owner.info)
|
createTypeBoundOpsLL(d.graph, env.typ, owner.info)
|
||||||
|
|
||||||
proc finishClosureCreation(owner: PSym; d: DetectionPass; c: LiftingPass;
|
proc finishClosureCreation(owner: PSym; d: DetectionPass; c: LiftingPass;
|
||||||
info: TLineInfo; res: PNode) =
|
info: TLineInfo; res: PNode) =
|
||||||
|
|
@ -638,8 +642,8 @@ proc closureCreationForIter(iter: PNode;
|
||||||
addVar(vs, vnode)
|
addVar(vs, vnode)
|
||||||
result.add(vs)
|
result.add(vs)
|
||||||
result.add(newCall(getSysSym(d.graph, iter.info, "internalNew"), vnode))
|
result.add(newCall(getSysSym(d.graph, iter.info, "internalNew"), vnode))
|
||||||
if optOwnedRefs in d.graph.config.globalOptions:
|
if d.graph.config.selectedGC in {gcHooks, gcDestructors}:
|
||||||
createTypeBoundOps(d.graph, nil, vnode.typ, iter.info)
|
createTypeBoundOpsLL(d.graph, vnode.typ, iter.info)
|
||||||
|
|
||||||
let upField = lookupInRecord(v.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
|
let upField = lookupInRecord(v.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
|
||||||
if upField != nil:
|
if upField != nil:
|
||||||
|
|
@ -924,8 +928,8 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
|
||||||
result.add(v)
|
result.add(v)
|
||||||
# add 'new' statement:
|
# add 'new' statement:
|
||||||
result.add(newCall(getSysSym(g, env.info, "internalNew"), env.newSymNode))
|
result.add(newCall(getSysSym(g, env.info, "internalNew"), env.newSymNode))
|
||||||
if optOwnedRefs in g.config.globalOptions:
|
if g.config.selectedGC in {gcHooks, gcDestructors}:
|
||||||
createTypeBoundOps(g, nil, env.typ, body.info)
|
createTypeBoundOpsLL(g, env.typ, body.info)
|
||||||
|
|
||||||
elif op.kind == nkStmtListExpr:
|
elif op.kind == nkStmtListExpr:
|
||||||
let closure = op.lastSon
|
let closure = op.lastSon
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue