closures have an object type field so that we can perform correct deepCopy() for the BoehmGC target

This commit is contained in:
Andreas Rumpf 2017-07-22 11:10:44 +02:00
commit ad608838bf
7 changed files with 40 additions and 19 deletions

View file

@ -164,11 +164,11 @@ proc genBreakState(p: BProc, n: PNode) =
if n.sons[0].kind == nkClosure:
# XXX this produces quite inefficient code!
initLocExpr(p, n.sons[0].sons[1], a)
lineF(p, cpsStmts, "if (((NI*) $1)[0] < 0) break;$n", [rdLoc(a)])
lineF(p, cpsStmts, "if (((NI*) $1)[1] < 0) break;$n", [rdLoc(a)])
else:
initLocExpr(p, n.sons[0], a)
# the environment is guaranteed to contain the 'state' field at offset 0:
lineF(p, cpsStmts, "if ((((NI*) $1.ClE_0)[0]) < 0) break;$n", [rdLoc(a)])
# the environment is guaranteed to contain the 'state' field at offset 1:
lineF(p, cpsStmts, "if ((((NI*) $1.ClE_0)[1]) < 0) break;$n", [rdLoc(a)])
# lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)])
proc genVarPrototypeAux(m: BModule, sym: PSym)

View file

@ -12,6 +12,7 @@
# ------------------------- Name Mangling --------------------------------
import sighashes
from lowerings import createObj
proc isKeyword(w: PIdent): bool =
# Nim and C++ share some keywords
@ -1092,7 +1093,8 @@ proc fakeClosureType(owner: PSym): PType =
result = newType(tyTuple, owner)
result.rawAddSon(newType(tyPointer, owner))
var r = newType(tyRef, owner)
r.rawAddSon(newType(tyTuple, owner))
let obj = createObj(owner, owner.info, final=false)
r.rawAddSon(obj)
result.rawAddSon(r)
type

View file

@ -142,7 +142,7 @@ proc createStateField(iter: PSym): PSym =
proc createEnvObj(owner: PSym; info: TLineInfo): PType =
# YYY meh, just add the state field for every closure for now, it's too
# hard to figure out if it comes from a closure iterator:
result = createObj(owner, info)
result = createObj(owner, info, final=false)
rawAddField(result, createStateField(owner))
proc getIterResult(iter: PSym): PSym =

View file

@ -109,17 +109,19 @@ proc lowerSwap*(n: PNode; owner: PSym): PNode =
result.add newFastAsgnStmt(n[1], n[2])
result.add newFastAsgnStmt(n[2], tempAsNode)
proc createObj*(owner: PSym, info: TLineInfo): PType =
proc createObj*(owner: PSym, info: TLineInfo; final=true): PType =
result = newType(tyObject, owner)
rawAddSon(result, nil)
incl result.flags, tfFinal
if final:
rawAddSon(result, nil)
incl result.flags, tfFinal
else:
rawAddSon(result, getCompilerProc("RootObj").typ)
result.n = newNodeI(nkRecList, info)
when true:
let s = newSym(skType, getIdent("Env_" & info.toFilename),
owner, info)
incl s.flags, sfAnon
s.typ = result
result.sym = s
let s = newSym(skType, getIdent("Env_" & info.toFilename),
owner, info)
incl s.flags, sfAnon
s.typ = result
result.sym = s
proc rawAddField*(obj: PType; field: PSym) =
assert field.kind == skField