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:
Andreas Rumpf 2020-10-25 08:50:47 +01:00 • committed by GitHub
commit 226595515c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 853 additions and 903 deletions

View file

@ -66,12 +66,13 @@ proc newFastMoveStmt*(g: ModuleGraph, le, ri: PNode): PNode =
result[1].add newSymNode(getSysMagic(g, ri.info, "move", mMove))
result[1].add ri
proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
assert n.kind == nkVarTuple
let value = n.lastSon
result = newNodeI(nkStmtList, n.info)
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), nextId(idgen),
owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
@ -85,12 +86,13 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
if n[i].kind == nkSym: v.addVar(n[i], val)
else: result.add newAsgnStmt(n[i], val)
proc evalOnce*(g: ModuleGraph; value: PNode; owner: PSym): PNode =
proc evalOnce*(g: ModuleGraph; value: PNode; idgen: IdGenerator; owner: PSym): PNode =
## Turns (value) into (let tmp = value; tmp) so that 'value' can be re-used
## freely, multiple times. This is frequently required and such a builtin would also be
## handy to have in macros.nim. The value that can be reused is 'result.lastSon'!
result = newNodeIT(nkStmtListExpr, value.info, value.typ)
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), nextId(idgen),
owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
@ -111,11 +113,11 @@ proc newTupleAccessRaw*(tup: PNode, i: int): PNode =
proc newTryFinally*(body, final: PNode): PNode =
result = newTree(nkHiddenTryStmt, body, newTree(nkFinally, final))
proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
let value = n.lastSon
result = newNodeI(nkStmtList, n.info)
var temp = newSym(skTemp, getIdent(g.cache, "_"), owner, value.info, owner.options)
var temp = newSym(skTemp, getIdent(g.cache, "_"), nextId(idgen), owner, value.info, owner.options)
var v = newNodeI(nkLetSection, value.info)
let tempAsNode = newSymNode(temp) #newIdentNode(getIdent(genPrefix & $temp.id), value.info)
@ -130,10 +132,10 @@ proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
for i in 0..<lhs.len:
result.add newAsgnStmt(lhs[i], newTupleAccessRaw(tempAsNode, i))
proc lowerSwap*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
proc lowerSwap*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
result = newNodeI(nkStmtList, n.info)
# note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
var temp = newSym(skVar, getIdent(g.cache, genPrefix), owner, n.info, owner.options)
var temp = newSym(skVar, getIdent(g.cache, genPrefix), nextId(idgen), owner, n.info, owner.options)
temp.typ = n[1].typ
incl(temp.flags, sfFromGeneric)
@ -150,8 +152,8 @@ proc lowerSwap*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
result.add newFastAsgnStmt(n[1], n[2])
result.add newFastAsgnStmt(n[2], tempAsNode)
proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType =
result = newType(tyObject, owner)
proc createObj*(g: ModuleGraph; idgen: IdGenerator; owner: PSym, info: TLineInfo; final=true): PType =
result = newType(tyObject, nextId(idgen), owner)
if final:
rawAddSon(result, nil)
incl result.flags, tfFinal
@ -159,6 +161,7 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType
rawAddSon(result, getCompilerProc(g, "RootObj").typ)
result.n = newNodeI(nkRecList, info)
let s = newSym(skType, getIdent(g.cache, "Env_" & toFilename(g.config, info) & "_" & $owner.name.s),
nextId(idgen),
owner, info, owner.options)
incl s.flags, sfAnon
s.typ = result
@ -196,7 +199,7 @@ proc rawDirectAccess*(obj, field: PSym): PNode =
result.add newSymNode(field)
result.typ = field.typ
proc lookupInRecord(n: PNode, id: int): PSym =
proc lookupInRecord(n: PNode, id: ItemId): PSym =
result = nil
case n.kind
of nkRecList:
@ -214,16 +217,16 @@ proc lookupInRecord(n: PNode, id: int): PSym =
if result != nil: return
else: discard
of nkSym:
if n.sym.id == -abs(id): result = n.sym
if n.sym.itemId.module == id.module and n.sym.itemId.item == -abs(id.item): result = n.sym
else: discard
proc addField*(obj: PType; s: PSym; cache: IdentCache) =
proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator) =
# because of 'gensym' support, we have to mangle the name with its ID.
# This is hacky but the clean solution is much more complex than it looks.
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len), s.owner, s.info,
s.options)
field.id = -s.id
let t = skipIntLit(s.typ)
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len),
nextId(idgen), s.owner, s.info, s.options)
field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
let t = skipIntLit(s.typ, idgen)
field.typ = t
assert t.kind != tyTyped
propagateToOwner(obj, t)
@ -232,13 +235,13 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) =
obj.n.add newSymNode(field)
fieldCheck()
proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable.} =
result = lookupInRecord(obj.n, s.id)
proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym {.discardable.} =
result = lookupInRecord(obj.n, s.itemId)
if result == nil:
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len), s.owner, s.info,
s.options)
field.id = -s.id
let t = skipIntLit(s.typ)
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len), nextId(idgen),
s.owner, s.info, s.options)
field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
let t = skipIntLit(s.typ, idgen)
field.typ = t
assert t.kind != tyTyped
propagateToOwner(obj, t)
@ -248,13 +251,13 @@ proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable
proc newDotExpr*(obj, b: PSym): PNode =
result = newNodeI(nkDotExpr, obj.info)
let field = lookupInRecord(obj.typ.n, b.id)
let field = lookupInRecord(obj.typ.n, b.itemId)
assert field != nil, b.name.s
result.add newSymNode(obj)
result.add newSymNode(field)
result.typ = field.typ
proc indirectAccess*(a: PNode, b: int, info: TLineInfo): PNode =
proc indirectAccess*(a: PNode, b: ItemId, info: TLineInfo): PNode =
# returns a[].b as a node
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst)[0]
@ -306,7 +309,7 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
var t = t
while true:
assert t.kind == tyObject
result = lookupInRecord(t.n, v.id)
result = lookupInRecord(t.n, v.itemId)
if result != nil: break
t = t[0]
if t == nil: break
@ -314,15 +317,15 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
proc indirectAccess*(a: PNode, b: PSym, info: TLineInfo): PNode =
# returns a[].b as a node
result = indirectAccess(a, b.id, info)
result = indirectAccess(a, b.itemId, info)
proc indirectAccess*(a, b: PSym, info: TLineInfo): PNode =
result = indirectAccess(newSymNode(a), b, info)
proc genAddrOf*(n: PNode, typeKind = tyPtr): PNode =
proc genAddrOf*(n: PNode; idgen: IdGenerator; typeKind = tyPtr): PNode =
result = newNodeI(nkAddr, n.info, 1)
result[0] = n
result.typ = newType(typeKind, n.typ.owner)
result.typ = newType(typeKind, nextId(idgen), n.typ.owner)
result.typ.rawAddSon(n.typ)
proc genDeref*(n: PNode; k = nkHiddenDeref): PNode =