explicit ID generation for easier IC (#15559)
* refactoring: idents don't need inheritance * refactoring: adding an IdGenerator (part 1) * refactoring: adding an IdGenerator (part 2) * refactoring: adding an IdGenerator (part 3) * refactoring: adding an IdGenerator (part 4) * refactoring: adding an IdGenerator (part 5) * refactoring: adding an IdGenerator (part 5) * IdGenerator must be a ref type; hello world works again * make bootstrapping work again * progress: add back the 'exactReplica' ideas * added back the missing exactReplica hacks * make tcompilerapi work again * make important packages green * attempt to fix the build for 32 bit machines (probably need a better solution here)
This commit is contained in:
parent
7252a50fef
commit
226595515c
67 changed files with 853 additions and 903 deletions
|
|
@ -27,12 +27,14 @@ type
|
|||
canRaise: bool
|
||||
filterDiscriminator: PSym # we generating destructor for case branch
|
||||
c: PContext # c can be nil, then we are called from lambdalifting!
|
||||
idgen: IdGenerator
|
||||
|
||||
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode)
|
||||
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
info: TLineInfo): PSym
|
||||
info: TLineInfo; idgen: IdGenerator): PSym
|
||||
|
||||
proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo)
|
||||
proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo;
|
||||
idgen: IdGenerator)
|
||||
|
||||
proc at(a, i: PNode, elemType: PType): PNode =
|
||||
result = newNodeI(nkBracketExpr, a.info, 2)
|
||||
|
|
@ -73,12 +75,12 @@ proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
call.typ = t
|
||||
body.add newAsgnStmt(x, call)
|
||||
|
||||
proc genAddr(g: ModuleGraph; x: PNode): PNode =
|
||||
proc genAddr(c: var TLiftCtx; x: PNode): PNode =
|
||||
if x.kind == nkHiddenDeref:
|
||||
checkSonsLen(x, 1, g.config)
|
||||
checkSonsLen(x, 1, c.g.config)
|
||||
result = x[0]
|
||||
else:
|
||||
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(x.typ.owner, x.typ))
|
||||
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(x.typ.owner, x.typ, c.idgen))
|
||||
result.add x
|
||||
|
||||
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
|
||||
|
|
@ -92,11 +94,11 @@ proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
|
|||
proc genIf(c: var TLiftCtx; cond, action: PNode): PNode =
|
||||
result = newTree(nkIfStmt, newTree(nkElifBranch, cond, action))
|
||||
|
||||
proc genContainerOf(c: TLiftCtx; objType: PType, field, x: PSym): PNode =
|
||||
proc genContainerOf(c: var TLiftCtx; objType: PType, field, x: PSym): PNode =
|
||||
# generate: cast[ptr ObjType](cast[int](addr(x)) - offsetOf(objType.field))
|
||||
let intType = getSysType(c.g, unknownLineInfo, tyInt)
|
||||
|
||||
let addrOf = newNodeIT(nkAddr, c.info, makePtrType(x.owner, x.typ))
|
||||
let addrOf = newNodeIT(nkAddr, c.info, makePtrType(x.owner, x.typ, c.idgen))
|
||||
addrOf.add newDeref(newSymNode(x))
|
||||
let castExpr1 = newNodeIT(nkCast, c.info, intType)
|
||||
castExpr1.add newNodeIT(nkType, c.info, intType)
|
||||
|
|
@ -113,7 +115,7 @@ proc genContainerOf(c: TLiftCtx; objType: PType, field, x: PSym): PNode =
|
|||
minusExpr.typ = intType
|
||||
minusExpr.add offsetOf
|
||||
|
||||
let objPtr = makePtrType(objType.owner, objType)
|
||||
let objPtr = makePtrType(objType.owner, objType, c.idgen)
|
||||
result = newNodeIT(nkCast, c.info, objPtr)
|
||||
result.add newNodeIT(nkType, c.info, objPtr)
|
||||
result.add minusExpr
|
||||
|
|
@ -121,7 +123,7 @@ proc genContainerOf(c: TLiftCtx; objType: PType, field, x: PSym): PNode =
|
|||
proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode =
|
||||
var destroy = newNodeIT(nkCall, x.info, op.typ[0])
|
||||
destroy.add(newSymNode(op))
|
||||
destroy.add genAddr(c.g, x)
|
||||
destroy.add genAddr(c, x)
|
||||
if sfNeverRaises notin op.flags:
|
||||
c.canRaise = true
|
||||
if c.addMemReset:
|
||||
|
|
@ -217,7 +219,7 @@ proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
|||
# for every field (dependent on dest.kind):
|
||||
# `=` dest.field, src.field
|
||||
# =destroy(blob)
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), c.fn, c.info)
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), nextId c.idgen, c.fn, c.info)
|
||||
temp.typ = x.typ
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
var v = newNodeI(nkVarSection, c.info)
|
||||
|
|
@ -251,7 +253,7 @@ proc newHookCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode =
|
|||
if sfNeverRaises notin op.flags:
|
||||
c.canRaise = true
|
||||
if op.typ.sons[1].kind == tyVar:
|
||||
result.add genAddr(c.g, x)
|
||||
result.add genAddr(c, x)
|
||||
else:
|
||||
result.add x
|
||||
if y != nil:
|
||||
|
|
@ -311,7 +313,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
|
|||
else:
|
||||
op = field
|
||||
if op == nil:
|
||||
op = produceSym(c.g, c.c, t, c.kind, c.info)
|
||||
op = produceSym(c.g, c.c, t, c.kind, c.info, c.idgen)
|
||||
if sfError in op.flags:
|
||||
incl c.fn.flags, sfError
|
||||
#else:
|
||||
|
|
@ -340,7 +342,7 @@ proc addDestructorCall(c: var TLiftCtx; orig: PType; body, x: PNode) =
|
|||
t.attachedOps[attachedDestructor] = op
|
||||
|
||||
if op == nil and (useNoGc(c, t) or requiresDestructor(c, t)):
|
||||
op = produceSym(c.g, c.c, t, attachedDestructor, c.info)
|
||||
op = produceSym(c.g, c.c, t, attachedDestructor, c.info, c.idgen)
|
||||
doAssert op != nil
|
||||
doAssert op == t.destructor
|
||||
|
||||
|
|
@ -381,7 +383,7 @@ proc considerUserDefinedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
|||
result = true
|
||||
|
||||
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), c.fn, c.info)
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), nextId(c.idgen), c.fn, c.info)
|
||||
temp.typ = getSysType(c.g, body.info, tyInt)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
|
||||
|
|
@ -452,7 +454,7 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
||||
|
||||
proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
createTypeBoundOps(c.g, c.c, t, body.info)
|
||||
createTypeBoundOps(c.g, c.c, t, body.info, c.idgen)
|
||||
# recursions are tricky, so we might need to forward the generated
|
||||
# operation here:
|
||||
var t = t
|
||||
|
|
@ -493,7 +495,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
case c.kind
|
||||
of attachedAsgn, attachedDeepCopy:
|
||||
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c.g, x), y)
|
||||
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c, x), y)
|
||||
of attachedSink:
|
||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
||||
moveCall.add y
|
||||
|
|
@ -509,7 +511,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
var actions = newNodeI(nkStmtList, c.info)
|
||||
let elemType = t.lastSon
|
||||
|
||||
createTypeBoundOps(c.g, c.c, elemType, c.info)
|
||||
createTypeBoundOps(c.g, c.c, elemType, c.info, c.idgen)
|
||||
|
||||
if isFinal(elemType):
|
||||
addDestructorCall(c, elemType, actions, genDeref(x, nkDerefExpr))
|
||||
|
|
@ -548,10 +550,10 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
if isFinal(elemType):
|
||||
let typInfo = genBuiltin(c.g, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType))
|
||||
typInfo.typ = getSysType(c.g, c.info, tyPointer)
|
||||
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x), typInfo, y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x, c.idgen), typInfo, y)
|
||||
else:
|
||||
# If the ref is polymorphic we have to account for this
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x), y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x, c.idgen), y)
|
||||
of attachedDispose:
|
||||
# this is crucial! dispose is like =destroy but we don't follow refs
|
||||
# as that is dealt within the cycle collector.
|
||||
|
|
@ -593,7 +595,7 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
body.add genIf(c, cond, actions)
|
||||
of attachedDeepCopy: assert(false, "cannot happen")
|
||||
of attachedTrace:
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(xenv), y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(xenv, c.idgen), y)
|
||||
of attachedDispose:
|
||||
# this is crucial! dispose is like =destroy but we don't follow refs
|
||||
# as that is dealt within the cycle collector.
|
||||
|
|
@ -788,28 +790,30 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
of tyOptDeprecated: doAssert false
|
||||
|
||||
proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType;
|
||||
kind: TTypeAttachedOp; info: TLineInfo): PSym =
|
||||
kind: TTypeAttachedOp; info: TLineInfo;
|
||||
idgen: IdGenerator): PSym =
|
||||
assert typ.kind == tyDistinct
|
||||
let baseType = typ[0]
|
||||
if baseType.attachedOps[kind] == nil:
|
||||
discard produceSym(g, c, baseType, kind, info)
|
||||
discard produceSym(g, c, baseType, kind, info, idgen)
|
||||
typ.attachedOps[kind] = baseType.attachedOps[kind]
|
||||
result = typ.attachedOps[kind]
|
||||
|
||||
proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp;
|
||||
info: TLineInfo): PSym =
|
||||
info: TLineInfo; idgen: IdGenerator): PSym =
|
||||
|
||||
let procname = getIdent(g.cache, AttachedOpToStr[kind])
|
||||
result = newSym(skProc, procname, owner, info)
|
||||
let dest = newSym(skParam, getIdent(g.cache, "dest"), result, info)
|
||||
let src = newSym(skParam, getIdent(g.cache, if kind == attachedTrace: "env" else: "src"), result, info)
|
||||
dest.typ = makeVarType(typ.owner, typ)
|
||||
result = newSym(skProc, procname, nextId(idgen), owner, info)
|
||||
let dest = newSym(skParam, getIdent(g.cache, "dest"), nextId(idgen), result, info)
|
||||
let src = newSym(skParam, getIdent(g.cache, if kind == attachedTrace: "env" else: "src"),
|
||||
nextId(idgen), result, info)
|
||||
dest.typ = makeVarType(typ.owner, typ, idgen)
|
||||
if kind == attachedTrace:
|
||||
src.typ = getSysType(g, info, tyPointer)
|
||||
else:
|
||||
src.typ = typ
|
||||
|
||||
result.typ = newProcType(info, owner)
|
||||
result.typ = newProcType(info, nextId(idgen), owner)
|
||||
result.typ.addParam dest
|
||||
if kind notin {attachedDestructor, attachedDispose}:
|
||||
result.typ.addParam src
|
||||
|
|
@ -825,15 +829,15 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp
|
|||
|
||||
|
||||
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
info: TLineInfo): PSym =
|
||||
info: TLineInfo; idgen: IdGenerator): PSym =
|
||||
if typ.kind == tyDistinct:
|
||||
return produceSymDistinctType(g, c, typ, kind, info)
|
||||
return produceSymDistinctType(g, c, typ, kind, info, idgen)
|
||||
|
||||
result = typ.attachedOps[kind]
|
||||
if result == nil:
|
||||
result = symPrototype(g, typ, typ.owner, kind, info)
|
||||
result = symPrototype(g, typ, typ.owner, kind, info, idgen)
|
||||
|
||||
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType:typ)
|
||||
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType:typ, idgen: idgen)
|
||||
a.fn = result
|
||||
|
||||
let dest = result.typ.n[1].sym
|
||||
|
|
@ -866,18 +870,19 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
|||
if not a.canRaise: incl result.flags, sfNeverRaises
|
||||
|
||||
|
||||
proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym, info: TLineInfo): PSym =
|
||||
proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym,
|
||||
info: TLineInfo; idgen: IdGenerator): PSym =
|
||||
assert(typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject)
|
||||
result = symPrototype(g, field.typ, typ.owner, attachedDestructor, info)
|
||||
var a = TLiftCtx(info: info, g: g, kind: attachedDestructor, asgnForType: typ)
|
||||
result = symPrototype(g, field.typ, typ.owner, attachedDestructor, info, idgen)
|
||||
var a = TLiftCtx(info: info, g: g, kind: attachedDestructor, asgnForType: typ, idgen: idgen)
|
||||
a.fn = result
|
||||
a.asgnForType = typ
|
||||
a.filterDiscriminator = field
|
||||
a.addMemReset = true
|
||||
let discrimantDest = result.typ.n[1].sym
|
||||
|
||||
let dst = newSym(skVar, getIdent(g.cache, "dest"), result, info)
|
||||
dst.typ = makePtrType(typ.owner, typ)
|
||||
let dst = newSym(skVar, getIdent(g.cache, "dest"), nextId(idgen), result, info)
|
||||
dst.typ = makePtrType(typ.owner, typ, idgen)
|
||||
let dstSym = newSymNode(dst)
|
||||
let d = newDeref(dstSym)
|
||||
let v = newNodeI(nkVarSection, info)
|
||||
|
|
@ -891,12 +896,12 @@ proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym,
|
|||
template liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
|
||||
discard "now a nop"
|
||||
|
||||
proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo) =
|
||||
proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo; idgen: IdGenerator) =
|
||||
if n.kind in nkCallKinds:
|
||||
if n[0].kind == nkSym and n[0].sym.magic == mDestroy:
|
||||
let t = n[1].typ.skipTypes(abstractVar)
|
||||
if t.destructor == nil:
|
||||
discard produceSym(g, c, t, attachedDestructor, info)
|
||||
discard produceSym(g, c, t, attachedDestructor, info, idgen)
|
||||
|
||||
if t.destructor != nil:
|
||||
if t.destructor.ast[genericParamsPos].kind != nkEmpty:
|
||||
|
|
@ -904,9 +909,9 @@ proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo) =
|
|||
if t.destructor.magic == mDestroy:
|
||||
internalError(g.config, info, "patching mDestroy with mDestroy?")
|
||||
n[0] = newSymNode(t.destructor)
|
||||
for x in n: patchBody(g, c, x, info)
|
||||
for x in n: patchBody(g, c, x, info, idgen)
|
||||
|
||||
template inst(field, t) =
|
||||
template inst(field, t, idgen) =
|
||||
if field.ast != nil and field.ast[genericParamsPos].kind != nkEmpty:
|
||||
if t.typeInst != nil:
|
||||
var a: TLiftCtx
|
||||
|
|
@ -914,17 +919,19 @@ template inst(field, t) =
|
|||
a.g = g
|
||||
a.kind = k
|
||||
a.c = c
|
||||
a.idgen = idgen
|
||||
|
||||
field = instantiateGeneric(a, field, t, t.typeInst)
|
||||
if field.ast != nil:
|
||||
patchBody(g, c, field.ast, info)
|
||||
patchBody(g, c, field.ast, info, a.idgen)
|
||||
else:
|
||||
localError(g.config, info, "unresolved generic parameter")
|
||||
|
||||
proc isTrival(s: PSym): bool {.inline.} =
|
||||
s == nil or (s.ast != nil and s.ast[bodyPos].len == 0)
|
||||
|
||||
proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo) =
|
||||
proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo;
|
||||
idgen: IdGenerator) =
|
||||
## In the semantic pass this is called in strategic places
|
||||
## to ensure we lift assignment, destructors and moves properly.
|
||||
## The later 'injectdestructors' pass depends on it.
|
||||
|
|
@ -959,14 +966,14 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
|
|||
for k in attachedDestructor..lastAttached:
|
||||
generics[k] = canon.attachedOps[k] != nil
|
||||
if not generics[k]:
|
||||
canon.attachedOps[k] = symPrototype(g, canon, canon.owner, k, info)
|
||||
canon.attachedOps[k] = symPrototype(g, canon, canon.owner, k, info, idgen)
|
||||
|
||||
# we generate the destructor first so that other operators can depend on it:
|
||||
for k in attachedDestructor..lastAttached:
|
||||
if not generics[k]:
|
||||
discard produceSym(g, c, canon, k, info)
|
||||
discard produceSym(g, c, canon, k, info, idgen)
|
||||
else:
|
||||
inst(canon.attachedOps[k], canon)
|
||||
inst(canon.attachedOps[k], canon, idgen)
|
||||
if canon != orig:
|
||||
orig.attachedOps[k] = canon.attachedOps[k]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue